ui

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2026 License: MIT Imports: 76 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ProseTargetCandidate is the minimum comfortable measure for chat prose.
	// On wide terminals chatProseWidth grows toward WorkWidth so the column
	// uses available space (Grok-style) instead of leaving a dead right margin.
	// Code fences, tables, diffs, and inspectors still use full WorkWidth.
	ProseTargetCandidate = 96
	// ProseTargetWide is the soft cap for conversational prose on very wide
	// terminals. Beyond this, long lines become harder to scan.
	ProseTargetWide = 140
)
View Source
const (
	ModeAsk   = ModeNormal
	ModeBuild = ModeAuto
)

Legacy source aliases keep embeddings and older tests compiling while saved ASK/BUILD values migrate through the session-version boundary below.

View Source
const ModalStackCapacity = 8

ModalStackCapacity bounds nested viewer state and prevents an accidental input loop from retaining an unbounded overlay chain.

View Source
const ProviderFailureCopy = "Provider unavailable. Check the provider profile and credential environment."

ProviderFailureCopy is host-owned presentation for provider failures. Raw provider/configuration errors can contain endpoints or backend prose and must never be sent to the transcript boundary.

Variables

View Source
var (
	ErrModalInvalid    = errors.New("invalid modal")
	ErrModalDuplicate  = errors.New("duplicate modal identity")
	ErrModalStackFull  = errors.New("modal stack is full")
	ErrModalStackEmpty = errors.New("modal stack is empty")
)
View Source
var (
	// ErrOutputDetailUnavailable deliberately conflates unknown, stale, and
	// evicted references. Callers must not infer whether a full result ever
	// existed from this transient viewer boundary.
	ErrOutputDetailUnavailable = errors.New("output detail is unavailable")
	// ErrOutputDetailCursor rejects cursors that do not identify a retained
	// row boundary. It never returns source content alongside the error.
	ErrOutputDetailCursor = errors.New("output detail cursor is invalid")
	// ErrOutputDetailPageBudget reports that the requested byte budget cannot
	// contain even the next complete UTF-8 rune. Returning an error avoids an
	// unchanged cursor loop and never emits malformed or missing source bytes.
	ErrOutputDetailPageBudget = errors.New("output detail page byte budget is too small")
	// ErrOutputDetailAdmissionLimit declines an ephemeral viewer capability
	// before sanitization when a source exceeds the bounded admission working
	// set. It does not affect the already-capped transcript receipt.
	ErrOutputDetailAdmissionLimit = errors.New("output detail exceeds the admission limit")
)
View Source
var ErrSessionStateRevisionUnknown = errors.New("session state revision is unknown; reload the durable session before saving")

Functions

func EncodeHeadlessGoalSessionState

func EncodeHeadlessGoalSessionState(messages []llm.Message, model, agentProfile string, modelPinned bool, executionCursor int64, snapshot goal.Snapshot) (string, error)

EncodeHeadlessGoalSessionState persists one headless turn together with the exact Goal Runtime snapshot that admitted and settled it.

func EncodeHeadlessGoalSessionStateWithContextFloor

func EncodeHeadlessGoalSessionStateWithContextFloor(messages []llm.Message, model, agentProfile string, modelPinned bool, executionCursor int64, snapshot goal.Snapshot, floor agent.ContextPromptFloor) (string, error)

EncodeHeadlessGoalSessionStateWithContextFloor persists a goal turn and its exact bounded provider-receipt floor as one session CAS payload.

func EncodeHeadlessGoalSessionStateWithProvider

func EncodeHeadlessGoalSessionStateWithProvider(
	messages []llm.Message,
	model, agentProfile string,
	modelPinned bool,
	executionCursor int64,
	snapshot goal.Snapshot,
	floor agent.ContextPromptFloor,
	provider SessionProviderIdentity,
) (string, error)

EncodeHeadlessGoalSessionStateWithProvider is the provider-bound Goal Runtime variant of EncodeHeadlessSessionStateWithProvider.

func EncodeHeadlessSessionState

func EncodeHeadlessSessionState(messages []llm.Message, model, agentProfile string, modelPinned bool, executionCursor int64) (string, error)

EncodeHeadlessSessionState creates a current-version snapshot that the interactive session picker can restore after a non-interactive run. Tool messages remain in model history, while the visible transcript stays focused on user and assistant text because headless mode has no persisted ToolCard state.

func EncodeHeadlessSessionStateWithContextFloor

func EncodeHeadlessSessionStateWithContextFloor(messages []llm.Message, model, agentProfile string, modelPinned bool, executionCursor int64, floor agent.ContextPromptFloor) (string, error)

EncodeHeadlessSessionStateWithContextFloor preserves the exact bounded provider-receipt floor when a headless session may later be resumed.

func EncodeHeadlessSessionStateWithProvider

func EncodeHeadlessSessionStateWithProvider(
	messages []llm.Message,
	model, agentProfile string,
	modelPinned bool,
	executionCursor int64,
	floor agent.ContextPromptFloor,
	provider SessionProviderIdentity,
) (string, error)

EncodeHeadlessSessionStateWithProvider preserves provider provenance for a session created outside the interactive Model.

func RenderGoalStatusLine

func RenderGoalStatusLine(summary GoalSummary, width int, isDark bool, themeID string, profiles ...GlyphProfile) string

RenderGoalStatusLine renders a single adaptive, width-safe status row for headers, composer chrome, or transient receipts. State is always conveyed by a glyph and text, never color alone.

func SetProseCap

func SetProseCap(columns int)

SetProseCap installs a fixed prose measure. Zero or negative restores the dynamic default. Call once at startup.

func ValidateTranscriptBlocks

func ValidateTranscriptBlocks(blocks []TranscriptBlock) error

ValidateTranscriptBlocks checks block-local invariants plus collection identity and parent-reference integrity. It expects a complete block set; parent order is intentionally not constrained, so forward references work.

Types

type Adapter

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

Adapter bridges the agent.Output interface to BubbleTea messages.

func NewAdapter

func NewAdapter(p *tea.Program, workDir ...string) *Adapter

NewAdapter creates an Adapter that sends messages to the given program.

func NewAdapterWithOutputDetails

func NewAdapterWithOutputDetails(p *tea.Program, store *OutputDetailStore, workDir ...string) *Adapter

NewAdapterWithOutputDetails creates an Adapter that can retain a bounded, terminal-safe, post-redaction prefix of ordinary unstructured tool output for the process-local viewer. Parser-private semantic payloads deliberately never cross this boundary.

func (*Adapter) BobWorkspaceContext

func (a *Adapter) BobWorkspaceContext(state agent.BobWorkspaceContextState)

BobWorkspaceContext forwards only the bounded semantic workspace digest. The adapter detaches the value so an agent-side cache update cannot mutate a message that Bubble Tea has not processed yet.

func (*Adapter) CapabilityRoute

func (a *Adapter) CapabilityRoute(route agent.CapabilityRoute)

func (*Adapter) ContextCompacted

func (a *Adapter) ContextCompacted()

func (*Adapter) ContextCompactionFinished

func (a *Adapter) ContextCompactionFinished()

func (*Adapter) ContextCompactionStarted

func (a *Adapter) ContextCompactionStarted()

func (*Adapter) ContinuationSuggestion

func (a *Adapter) ContinuationSuggestion(turnID string, sequence uint64, suggestion *agent.ContinuationSuggestion)

ContinuationSuggestion forwards only the already bounded presentation. Tool arguments, workspace references, command strings, and raw receipt content never cross into Bubble Tea state.

func (*Adapter) Error

func (a *Adapter) Error(msg string)

func (*Adapter) StreamDone

func (a *Adapter) StreamDone(evalCount, promptTokens int)

func (*Adapter) StreamReasoning

func (a *Adapter) StreamReasoning(text string)

func (*Adapter) StreamText

func (a *Adapter) StreamText(text string)

func (*Adapter) SystemMessage

func (a *Adapter) SystemMessage(msg string)

func (*Adapter) ToolCallResult

func (a *Adapter) ToolCallResult(callID, name string, result string, isError bool, duration time.Duration)

func (*Adapter) ToolCallSemanticResult

func (a *Adapter) ToolCallSemanticResult(callID, name string, result string, isError bool, duration time.Duration, projection ecosystem.ToolProjection)

ToolCallSemanticResult carries only the bounded host projection into the UI; raw StructuredContent remains inside the agent parser boundary.

func (*Adapter) ToolCallSemanticResultWithDetail

func (a *Adapter) ToolCallSemanticResultWithDetail(
	callID, name string,
	result string,
	isError bool,
	duration time.Duration,
	projection ecosystem.ToolProjection,
	detail *agent.ToolOutputDetail,
)

ToolCallSemanticResultWithDetail admits only an explicit complete, post-redaction unstructured payload. The payload is consumed synchronously by the bounded process-local store; Bubble Tea receives only an opaque capability and scalar digest.

func (*Adapter) ToolCallStart

func (a *Adapter) ToolCallStart(callID, name string, args map[string]any)

type AgentDoneMsg

type AgentDoneMsg struct {
	// TurnID is the logical user/Goal turn identity. SegmentTurnID is the
	// execution-ledger identity used by the just-finished AUTO segment. They are
	// equal for ordinary turns; a productive AUTO checkpoint keeps TurnID stable
	// while continuing under a fresh SegmentTurnID.
	TurnID        string
	SegmentTurnID string
	Err           error
}

AgentDoneMsg signals the agent loop has completed.

type AgentPickerState

type AgentPickerState struct {
	List list.Model
}

type AnchorBias

type AnchorBias uint8

AnchorBias controls which neighboring block is preferred when the anchored block no longer survives in the current transcript.

const (
	AnchorBiasNext AnchorBias = iota
	AnchorBiasPrevious
)

type AnchorResolutionReason

type AnchorResolutionReason uint8

AnchorResolutionReason records whether the requested semantic point survived or which deterministic fallback selected the resolved block.

const (
	AnchorResolutionFollowLatest AnchorResolutionReason = iota
	AnchorResolutionExactBlock
	AnchorResolutionNextBlock
	AnchorResolutionPreviousBlock
	AnchorResolutionTurnStart
	AnchorResolutionDocumentTop
)

type ApprovalPosture

type ApprovalPosture string

ApprovalPosture is the process-wide approval contract selected by the host. It is presentation state only: the permission checker remains the execution authority, while the TUI makes that authority visible without inferring it from conversational mode.

const (
	ApprovalPosturePrompted             ApprovalPosture = "prompted"
	ApprovalPostureSkipApprovals        ApprovalPosture = "skip_approvals"
	ApprovalPostureAcceptWorkspaceEdits ApprovalPosture = "accept_workspace_edits"
	// ApprovalPostureYolo is retained for source compatibility.
	// Deprecated: use ApprovalPostureSkipApprovals.
	ApprovalPostureYolo = ApprovalPostureSkipApprovals
)

type ApprovalState

type ApprovalState struct {
	Viewport      viewport.Model
	ShowArguments bool
	ChoiceIndex   int
}

ApprovalState owns presentation-only state for an approval request. The root Model remains responsible for every decision and side effect.

type BlockID

type BlockID string

BlockID is the durable identity of one semantic transcript block. It must remain stable across streaming updates, reflow, persistence, and restore.

func NewBlockID

func NewBlockID() (BlockID, error)

NewBlockID returns a process-independent 128-bit block identity.

func (BlockID) Valid

func (id BlockID) Valid() bool

Valid reports whether id is a bounded, canonical opaque identity. IDs are intentionally not restricted to the generated prefix so existing durable execution identities can be projected without being rewritten.

type BlockKind

type BlockKind uint8

BlockKind describes a block's semantic role. Rendering, width, theme, focus, and expansion state are deliberately absent from this enum.

const (
	BlockKindUnknown BlockKind = iota
	BlockKindUserMessage
	BlockKindAssistantMessage
	BlockKindReasoningSummary
	BlockKindToolGroup
	BlockKindToolCall
	BlockKindAgentGroup
	BlockKindAgentEvent
	BlockKindPermissionReceipt
	BlockKindQuestionReceipt
	BlockKindPlanEvent
	BlockKindSystemNotice
	BlockKindErrorNotice
	BlockKindCompactionEvent
	BlockKindSessionBoundary
)

func (BlockKind) Valid

func (kind BlockKind) Valid() bool

Valid reports whether kind names a supported semantic block.

type BlockLifecycle

type BlockLifecycle uint8

BlockLifecycle is the monotonic semantic lifecycle of a transcript block.

const (
	BlockPending BlockLifecycle = iota
	BlockLive
	BlockSettling
	BlockSettled
	BlockFailed
	BlockCancelled
)

func (BlockLifecycle) CanTransitionTo

func (lifecycle BlockLifecycle) CanTransitionTo(next BlockLifecycle) bool

CanTransitionTo enforces the lifecycle partial order. It accepts an idempotent transition and rejects every transition out of a terminal state.

func (BlockLifecycle) Terminal

func (lifecycle BlockLifecycle) Terminal() bool

Terminal reports whether the block can no longer make a semantic transition. Re-applying the same terminal state remains idempotent.

func (BlockLifecycle) Valid

func (lifecycle BlockLifecycle) Valid() bool

Valid reports whether lifecycle is a known lifecycle value.

type BlockPayload

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

BlockPayload is the deliberately narrow, provider-neutral content admitted to the transcript model. Every field must already be terminal-safe and host-approved before construction. In particular, callers must not place raw MCP StructuredContent, provider reasoning, internal prompts, credentials, or unredacted private paths in these strings.

Tool transport/domain/evidence projections remain separate typed models; they must not be smuggled into this payload as arbitrary maps.

func NewHostProjectedBlockPayload

func NewHostProjectedBlockPayload(label, safeSummary string) (BlockPayload, error)

NewHostProjectedBlockPayload admits bounded host-authored chrome and a summary explicitly approved for display. It is the only constructor for labels/summaries and must never receive private provider reasoning.

func NewVisibleTextBlockPayload

func NewVisibleTextBlockPayload(visibleText string) (BlockPayload, error)

NewVisibleTextBlockPayload admits already projected user/assistant text. It does not accept tool envelopes; MCP results must first cross the bounded parser/ecosystem projection boundary.

func (BlockPayload) Label

func (payload BlockPayload) Label() string

Label returns canonical single-line host chrome.

func (BlockPayload) MarshalJSON

func (BlockPayload) MarshalJSON() ([]byte, error)

MarshalJSON fails closed. Durable transcript envelopes need an explicit projection so adding a field here cannot silently persist private content.

func (BlockPayload) SafeSummary

func (payload BlockPayload) SafeSummary() string

SafeSummary returns a canonical single-line, host-approved summary.

func (*BlockPayload) UnmarshalJSON

func (*BlockPayload) UnmarshalJSON([]byte) error

UnmarshalJSON fails closed for the same reason as MarshalJSON. Restore must validate an explicit, versioned durable DTO before constructing this type.

func (BlockPayload) VisibleText

func (payload BlockPayload) VisibleText() string

VisibleText returns terminal-safe projected message text.

type BobWorkspaceContextMsg

type BobWorkspaceContextMsg struct {
	Generation uint64
	Digest     *ecosystem.ReceiptDigest
}

BobWorkspaceContextMsg replaces the ephemeral bounded Bob workspace status. Generation is monotonic for one Agent lifetime; a nil digest is an authoritative clear. Raw Bob output never crosses into Bubble Tea state.

type CapabilityRouteMsg

type CapabilityRouteMsg struct {
	Route agent.CapabilityRoute
}

CapabilityRouteMsg is an ephemeral host advisory. It must never be appended to ChatEntry, ToolEntry, session state, or evidence receipts.

type CellRect

type CellRect struct {
	MinX int
	MinY int
	MaxX int
	MaxY int
}

CellRect describes a half-open rectangle of terminal cells: [MinX, MaxX) x [MinY, MaxY). The zero value is an empty rectangle.

func Inset

func Inset(rect CellRect, insets Insets) CellRect

Inset applies insets without allowing either axis to cross. If opposing insets exceed the available extent, the top or left inset is satisfied first and the result collapses to an empty axis.

func NewCellRect

func NewCellRect(minX, minY, maxX, maxY int) CellRect

NewCellRect creates a canonical half-open rectangle from its bounds. Inverted axes collapse at their minimum coordinate instead of producing a negative extent.

func TakeBottom

func TakeBottom(rect CellRect, n int) (taken, remain CellRect)

TakeBottom removes up to n rows from the bottom of rect. It returns the removed rectangle first and the remaining rectangle second.

func TakeLeft

func TakeLeft(rect CellRect, n int) (taken, remain CellRect)

TakeLeft removes up to n columns from the left of rect. It returns the removed rectangle first and the remaining rectangle second.

func TakeRight

func TakeRight(rect CellRect, n int) (taken, remain CellRect)

TakeRight removes up to n columns from the right of rect. It returns the removed rectangle first and the remaining rectangle second.

func TakeTop

func TakeTop(rect CellRect, n int) (taken, remain CellRect)

TakeTop removes up to n rows from the top of rect. It returns the removed rectangle first and the remaining rectangle second.

func (CellRect) Contains

func (r CellRect) Contains(x, y int) bool

Contains reports whether the terminal cell at (x, y) is inside the rectangle. Cells on MaxX or MaxY are outside by the half-open contract.

func (CellRect) Empty

func (r CellRect) Empty() bool

Empty reports whether the rectangle contains no terminal cells.

func (CellRect) Height

func (r CellRect) Height() int

Height returns the rectangle's non-negative vertical extent.

func (CellRect) Width

func (r CellRect) Width() int

Width returns the rectangle's non-negative horizontal extent.

type ChatEntry

type ChatEntry struct {
	BlockID           BlockID          // stable semantic identity across reflow and restore
	TurnID            TurnID           // causal turn identity; independent of slice position
	Revision          uint64           // semantic/lifecycle revision, never a layout revision
	Lifecycle         BlockLifecycle   // monotonic semantic lifecycle
	Kind              string           // "user", "assistant", "tool_group", "error", "system"
	Content           string           // raw content
	RenderedContent   string           // cached Glamour output (set once on completion)
	Name              string           // tool name for tool entries
	IsError           bool             // for tool_result
	ToolIndex         int              // index into toolEntries for "tool_group" kind
	ThinkingContent   string           // extracted <think> content
	ThinkingCollapsed bool             // default: true
	Attachments       []imageasset.Ref // validated, path-free image metadata
	// contains filtered or unexported fields
}

ChatEntry is a single item in the chat log.

type ClipboardImagePasteMsg

type ClipboardImagePasteMsg struct {
	Name string
	Data []byte
	Err  error
}

ClipboardImagePasteMsg carries one explicitly requested clipboard image only until the parent can admit it to the private content-addressed store. Raw bytes never enter Model state, transcript entries, or session persistence.

type CommandResultMsg

type CommandResultMsg struct {
	Text string
}

CommandResultMsg carries the result of a slash command for display.

type CommitResultMsg

type CommitResultMsg struct {
	Token   uint64
	Message string // commit message used
	Err     error
}

CommitResultMsg carries the result of an async /commit operation.

type Completer

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

func NewCompleter

func NewCompleter(cmdReg *command.Registry, models, skills, agents []string, _ *mcp.Registry) *Completer

func (*Completer) Complete

func (c *Completer) Complete(input string) []Completion

func (*Completer) CompleteFilePath

func (c *Completer) CompleteFilePath(relPath string) []Completion

CompleteFilePath lists directory contents at a given relative path. Used for folder drill-down in the completion modal.

func (*Completer) CompleteStatic

func (c *Completer) CompleteStatic(input string) []Completion

CompleteStatic returns only in-memory completion sources. The UI uses this from Update so filesystem listing and walking are always deferred to a cancellable tea.Cmd.

func (*Completer) SearchFiles

func (c *Completer) SearchFiles(ctx context.Context, query string) []Completion

SearchFiles performs a bounded, cancellation-aware filename search inside the workspace. Completion must never invoke MCP behind the permission and profile-scope broker; semantic search remains an explicit Cortex/MCP action.

func (*Completer) SetIgnorePatterns

func (c *Completer) SetIgnorePatterns(patterns *config.IgnorePatterns)

SetIgnorePatterns sets the ignore patterns used to filter file completions.

func (*Completer) UpdateAgents

func (c *Completer) UpdateAgents(agents []string)

func (*Completer) UpdateModels

func (c *Completer) UpdateModels(models []string)

func (*Completer) UpdateProviders

func (c *Completer) UpdateProviders(providers []string)

func (*Completer) UpdateSkills

func (c *Completer) UpdateSkills(skills []string)

func (*Completer) WorkspaceCompletions

func (c *Completer) WorkspaceCompletions(ctx context.Context, query, currentPath string) []Completion

WorkspaceCompletions performs every filesystem-backed completion operation. Callers must run it inside a tea.Cmd; context cancellation stops directory iteration and the bounded recursive search as soon as control returns from the underlying filesystem call.

type Completion

type Completion struct {
	Label       string
	Insert      string
	Category    string
	Description string
	SearchTerms string
	Index       int
}

func FilterCompletions

func FilterCompletions(items []Completion, query string) []Completion

FilterCompletions searches visible labels, useful descriptions, and hidden metadata such as command aliases without turning aliases into duplicate rows.

type CompletionDebounceTickMsg

type CompletionDebounceTickMsg struct {
	Generation uint64
	Tag        int
	Query      string
	Path       string
}

CompletionDebounceTickMsg fires after the debounce interval to trigger a search.

type CompletionSearchResultMsg

type CompletionSearchResultMsg struct {
	Generation uint64
	Tag        int
	Results    []Completion
}

CompletionSearchResultMsg delivers async vecgrep search results.

type CompletionState

type CompletionState struct {
	Kind          string          // "command", "attachments", "skills"
	Filter        textinput.Model // inline filter field
	Anchor        completionAnchor
	CommandPrefix string       // exact `/command ` prefix for registry action completion
	BaseItems     []Completion // non-workspace items retained across async searches
	AllItems      []Completion // full unfiltered list
	FilteredItems []Completion // items matching current filter
	Index         int          // cursor in FilteredItems
	Selected      map[int]bool // multi-select (keys = AllItems indices)
	CurrentPath   string       // for @ file browsing: relative dir path
	Searching     bool         // true while vecgrep is in flight
	Generation    uint64       // guards results across close/reopen cycles
	DebounceTag   int          // cancel stale searches
	SearchCancel  context.CancelFunc
	Preview       completionPreview
	PreviewToken  uint64
	PreviewCancel context.CancelFunc
}

CompletionState holds all state for the composer-owned completion popup.

type ContentGrid

type ContentGrid struct {
	PaneWidth int
	Profile   GlyphProfile
}

ContentGrid is the single owner of transcript content-column geometry for a pane width and glyph profile. It does not own density or truncation budgets.

func (ContentGrid) ContentWidth

func (g ContentGrid) ContentWidth() int

ContentWidth is the flex column budget for semantic text. It matches chatContentWidth numerically: pane minus left and right chrome, floored at transcriptMinimumWorkColumns so caches stay stable on very narrow panes.

func (ContentGrid) IndentBlock

func (g ContentGrid) IndentBlock(accent, block string) string

IndentBlock prefixes every non-empty line with Prefix(accent). Empty lines stay empty so vertical rhythm is preserved.

func (ContentGrid) Line

func (g ContentGrid) Line(accent, content string) string

Line paints one grid row: Prefix(accent) plus content truncated to ContentWidth.

func (ContentGrid) LineWidth

func (g ContentGrid) LineWidth() int

LineWidth is accent + pad + content (= pane − right chrome when not floored).

func (ContentGrid) OriginX

func (g ContentGrid) OriginX() int

OriginX is the pane-relative column where semantic content begins. It is always contentLeftColumns and never density-dependent.

func (ContentGrid) Prefix

func (g ContentGrid) Prefix(accent string) string

Prefix forces accent to one display cell and appends the two-cell left pad. Empty accents become a single space so OriginX stays aligned.

type ContextCompactedMsg

type ContextCompactedMsg struct{}

ContextCompactedMsg invalidates the previous provider occupancy snapshot. The retained history is smaller, but its next exact prompt size is not known until Ollama reports the following request.

type ContextCompactionFinishedMsg

type ContextCompactionFinishedMsg struct{}

type ContextCompactionStartedMsg

type ContextCompactionStartedMsg struct{}

ContextCompactionStartedMsg and ContextCompactionFinishedMsg expose the hidden summarization request as one explicit UI phase. They carry no model text or transcript data.

type ContextDoctorMsg

type ContextDoctorMsg struct {
	RequestID uint64
	Breakdown agent.ContextBreakdown
}

ContextDoctorMsg carries one measured breakdown back to the open overlay.

type ContextDoctorState

type ContextDoctorState struct {
	Breakdown agent.ContextBreakdown
	Loaded    bool
	// contains filtered or unexported fields
}

ContextDoctorState is the transient context-usage viewer. It holds presentation state only; measurements come from the agent snapshot.

type ContextLoadResultMsg

type ContextLoadResultMsg struct {
	Token uint64
	Path  string
	Data  string
	Err   error
}

ContextLoadResultMsg completes a bounded asynchronous /load operation.

type ContinuationActionMsg

type ContinuationActionMsg struct {
	TurnID   string
	Sequence uint64
	Action   *ContinuationActionPresentation
}

ContinuationActionMsg atomically replaces the ephemeral suggestion for one active turn. Sequence is monotonic within TurnID; a nil Action is an authoritative clear. Neither the message nor its presentation is persisted.

type ContinuationActionPresentation

type ContinuationActionPresentation struct {
	Tool       string
	Inputs     []string
	BlockedBy  []string
	ReasonCode string
}

ContinuationActionPresentation is the UI-facing projection of one validated continuation suggestion. It deliberately excludes arguments, command text, workspace references, and arbitrary downstream prose. The agent adapter may populate it only after the exact continuation interpreter has accepted the source contract.

type CoreReadyMsg

type CoreReadyMsg struct {
	Model                    string
	ModelList                []string
	OllamaModels             []OllamaModelDescriptor
	OllamaInventoryAttempted bool
	AgentProfile             string
	NumCtx                   int
}

CoreReadyMsg signals that the host has committed the startup model and agent profile, so ordinary turns may run even while optional MCP/ICE work continues in the background.

type DiffFileProjection

type DiffFileProjection struct {
	ID          string
	DisplayPath string
	Lines       []DiffLine
	Truncated   bool
	Revision    uint64
}

DiffFileProjection is the immutable, presentation-safe input for one file. DisplayPath is re-sanitized and confined to a workspace-relative label by NewDiffViewer. Revision zero represents a producer that has not published a complete first projection yet.

type DiffHunk

type DiffHunk struct {
	OldStart int `json:"OldStart,omitempty"`
	OldCount int `json:"OldCount,omitempty"`
	NewStart int `json:"NewStart,omitempty"`
	NewCount int `json:"NewCount,omitempty"`
}

DiffHunk is the structural range represented by one unified-diff hunk. Keeping the range typed means rendering and session restore never need to reverse-engineer coordinates from already-styled text.

type DiffLine

type DiffLine struct {
	Kind    DiffLineKind
	Content string
	OldLine int       `json:"OldLine,omitempty"`
	NewLine int       `json:"NewLine,omitempty"`
	Hunk    *DiffHunk `json:"Hunk,omitempty"`
}

DiffLine is a single line in a unified diff.

type DiffLineKind

type DiffLineKind int

DiffLineKind represents the type of a diff line.

const (
	DiffContext DiffLineKind = iota
	DiffAdded
	DiffRemoved
	DiffHunkHeader
	DiffEllipsis
	DiffOmitted
	DiffNoNewline
)

type DiffViewer

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

DiffViewer is a presentation-only Charm component. Its files are cloned on admission; Bubbles owns scrolling and search editing while the parent owns every side effect described by DiffViewerEvent.

func NewDiffViewer

func NewDiffViewer(
	origin BlockID,
	files []DiffFileProjection,
	options DiffViewerOptions,
) *DiffViewer

NewDiffViewer constructs a viewer in unified mode. Invalid or absolute display paths are reduced to a safe relative basename before entering state.

func (*DiffViewer) Back

func (viewer *DiffViewer) Back() bool

Back consumes Escape while search owns focus. False means the parent may close the modal.

func (*DiffViewer) CurrentAnchor

func (viewer *DiffViewer) CurrentAnchor() DiffViewerAnchor

func (*DiffViewer) CurrentFileIndex

func (viewer *DiffViewer) CurrentFileIndex() int

func (*DiffViewer) EffectiveMode

func (viewer *DiffViewer) EffectiveMode() DiffViewerMode

func (*DiffViewer) Layout

func (viewer *DiffViewer) Layout() DiffViewerLayout

Layout returns the exact geometry and resolved mode consumed by View.

func (*DiffViewer) PreferredMode

func (viewer *DiffViewer) PreferredMode() DiffViewerMode

func (*DiffViewer) SetFiles

func (viewer *DiffViewer) SetFiles(files []DiffFileProjection)

SetFiles replaces an immutable producer projection without resetting the user's mode preference or semantic cursor. A live pending diff can therefore become complete in place; stale per-file cursors are discarded.

func (*DiffViewer) SetReducedMotion

func (viewer *DiffViewer) SetReducedMotion(reduced bool)

SetReducedMotion disables the search cursor blink without conflating motion, glyph capability, or color. The semantic anchor and frame allocation do not change.

func (*DiffViewer) SetScreenRect

func (viewer *DiffViewer) SetScreenRect(rect CellRect)

SetScreenRect is the non-zero-origin counterpart used by a parent that has already allocated a screen sub-rectangle.

func (*DiffViewer) SetSize

func (viewer *DiffViewer) SetSize(width, height int)

SetSize recomputes modal, BodyRect, capability, and wrapped-row geometry. Preferred split survives a narrow fallback and is restored when it fits.

func (*DiffViewer) SetTheme

func (viewer *DiffViewer) SetTheme(isDark bool, themeID string)

SetTheme refreshes every adaptive style while preserving mode, semantic selection, search state, and geometry.

func (*DiffViewer) Update

func (viewer *DiffViewer) Update(msg tea.Msg) (DiffViewerEvent, tea.Cmd)

Update handles presentation input and returns a bounded parent intent.

func (*DiffViewer) View

func (viewer *DiffViewer) View() string

View renders a frame-local modal. Its exact placement is described by Layout().OuterRect; the parent may center/overlay this frame without asking the child to infer the base transcript geometry.

func (*DiffViewer) ViewWithCursor

func (viewer *DiffViewer) ViewWithCursor() (string, *tea.Cursor)

ViewWithCursor renders the modal and a cursor local to the returned frame.

type DiffViewerAction

type DiffViewerAction uint8

DiffViewerAction identifies which user request was unavailable.

const (
	DiffViewerActionNone DiffViewerAction = iota
	DiffViewerActionCopyLine
	DiffViewerActionCopyHunk
	DiffViewerActionCopyPath
)

type DiffViewerAnchor

type DiffViewerAnchor struct {
	FileID        string
	LineIndex     int
	PeerLineIndex int
	Continuation  int
	Side          DiffViewerSide
}

DiffViewerAnchor binds a physical wrapped row to stable source identity. Continuation zero is the first painted row of a logical DiffLine. Split rows retain both source indices because removed and added lines may share a row.

type DiffViewerEvent

type DiffViewerEvent struct {
	Kind           DiffViewerEventKind
	Action         DiffViewerAction
	BlockID        BlockID
	FileID         string
	FileIndex      int
	HunkIndex      int
	LineIndex      int
	Text           string
	Truncated      bool
	DisabledReason string
}

DiffViewerEvent is a bounded scalar request for the smart parent. BlockID remains the original transcript authority across file, hunk, and line navigation. Text contains terminal-safe plain text only.

type DiffViewerEventKind

type DiffViewerEventKind uint8

DiffViewerEventKind names a parent-owned side effect request. The component never calls a clipboard implementation and never appends a transcript row.

const (
	DiffViewerEventNone DiffViewerEventKind = iota
	DiffViewerEventCopyLine
	DiffViewerEventCopyHunk
	DiffViewerEventCopyPath
	DiffViewerEventUnavailable
)

type DiffViewerLayout

type DiffViewerLayout struct {
	ScreenRect CellRect
	OuterRect  CellRect
	InnerRect  CellRect
	HeaderRect CellRect
	SearchRect CellRect
	BodyRect   CellRect
	FooterRect CellRect

	PreferredMode    DiffViewerMode
	EffectiveMode    DiffViewerMode
	ShowNumbers      bool
	UnifiedCodeWidth int
	OldCodeWidth     int
	NewCodeWidth     int
	OldDigits        int
	NewDigits        int
	SplitAvailable   bool
	UnifiedAvailable bool
	DisabledReason   string
}

DiffViewerLayout is the exact half-open geometry used for both capability decisions and paint. Rectangles are expressed in screen coordinates.

type DiffViewerMode

type DiffViewerMode uint8

DiffViewerMode separates the user's durable presentation preference from the mode that fits the current BodyRect.

const (
	DiffViewerUnified DiffViewerMode = iota
	DiffViewerSplit
)

func (DiffViewerMode) String

func (mode DiffViewerMode) String() string

type DiffViewerOptions

type DiffViewerOptions struct {
	Width         int
	Height        int
	IsDark        bool
	ThemeID       string
	ReducedMotion bool
	GlyphProfile  GlyphProfile
}

DiffViewerOptions supplies presentation-only host state.

type DiffViewerSide

type DiffViewerSide uint8

DiffViewerSide identifies the logical side selected within a split row. Unified rows use DiffViewerSideUnified.

const (
	DiffViewerSideUnified DiffViewerSide = iota
	DiffViewerSideOld
	DiffViewerSideNew
)

type EntityKind

type EntityKind uint8

EntityKind identifies the scalar domain identity carried by a UI action. The reference deliberately excludes presentation models, raw tool payloads, and provider objects.

const (
	EntityKindNone EntityKind = iota
	EntityKindTranscriptBlock
	EntityKindToolInvocation
	EntityKindAgentInvocation
	EntityKindOverlay
	EntityKindDiffLocation
)

func (EntityKind) Valid

func (kind EntityKind) Valid() bool

Valid reports whether kind is a supported action target category.

type EntityRef

type EntityRef struct {
	Kind         EntityKind
	BlockID      BlockID
	InvocationID string
	OverlayID    OverlayID
	FileIndex    int
	HunkIndex    int
	LineIndex    int
}

EntityRef is the complete target admitted across the UI action boundary. Every field is scalar so keyboard and pointer input produce the same inspectable request without closures or raw domain payloads.

func (EntityRef) Valid

func (ref EntityRef) Valid() bool

Valid reports whether ref contains the minimum identity required by its category. Extra scalar ancestry is allowed (for example, a diff location may retain both its transcript block and tool invocation).

type ErrorMsg

type ErrorMsg struct {
	Msg string
}

ErrorMsg reports an error.

type ExportResultMsg

type ExportResultMsg struct {
	Token uint64
	Path  string
	Err   error
}

ExportResultMsg reports the outcome of an atomic asynchronous /export.

type FailedServer

type FailedServer struct {
	Name   string
	Reason string
}

FailedServer records an MCP server that failed to connect.

type FocusOwner

type FocusOwner uint8

FocusOwner identifies a stable, scalar focus destination.

const (
	FocusOwnerUnknown FocusOwner = iota
	FocusOwnerComposer
	FocusOwnerTranscript
	FocusOwnerModal
)

func (FocusOwner) Valid

func (owner FocusOwner) Valid() bool

Valid reports whether owner can receive restored focus.

type FocusToken

type FocusToken struct {
	Owner     FocusOwner
	OverlayID OverlayID
	ControlID string
}

FocusToken identifies a focus destination without retaining a Bubbles model or callback. ControlID optionally identifies a child control within a modal.

func DefaultFocusToken

func DefaultFocusToken() FocusToken

DefaultFocusToken is the final focus fallback after a modal chain closes.

func (FocusToken) Valid

func (token FocusToken) Valid() bool

Valid reports whether token is internally consistent and terminal-safe.

type FrameProjection

type FrameProjection struct {
	Screen              CellRect
	SafeScreen          CellRect
	WidthClass          WidthClass
	HeightClass         HeightClass
	TranscriptFloorRows int
	VerticalFit         FrameVerticalFit
	Header              FrameSurfaceProjection
	Transcript          FrameSurfaceProjection
	Footer              FrameSurfaceProjection
	Cursor              *tea.Cursor
}

FrameProjection is the single geometry snapshot consumed by View and by viewport sizing. Header (session chrome), transcript, and footer stack vertically; overlays remain a z-layer over these stable base rectangles.

type FrameSurfaceProjection

type FrameSurfaceProjection struct {
	Rect    CellRect
	Content string
	Visible bool
}

FrameSurfaceProjection binds painted content to the exact half-open cell rectangle owned by that surface.

type FrameVerticalFit

type FrameVerticalFit uint8

FrameVerticalFit records which vertical policy produced the frame. It keeps cramped layouts observable without making View infer intent from rectangle sizes.

const (
	// FrameVerticalComfortable means the complete footer, including ordinary
	// separation chrome, fit alongside the transcript floor.
	FrameVerticalComfortable FrameVerticalFit = iota
	// FrameVerticalCondensed means only redundant divider/spacing rows were
	// removed to preserve the transcript floor. No control or authored footer
	// content was hidden.
	FrameVerticalCondensed
	// FrameVerticalOwnerPriority means the footer's critical controls alone
	// exceeded the remaining rows. The controls remain complete and the
	// transcript receives the physical remainder, which can be below its floor.
	FrameVerticalOwnerPriority
	// FrameVerticalRecovery means the terminal-size recovery surface replaces
	// the base transcript/footer entirely. Its geometry remains canonical, but
	// neither base surface is painted.
	FrameVerticalRecovery
)

type GlyphProfile

type GlyphProfile uint8

GlyphProfile selects terminal-safe symbols independently from color and motion preferences. NO_COLOR must never silently imply ASCII: a terminal may support Unicode while intentionally disabling color.

const (
	GlyphUnicode GlyphProfile = iota
	GlyphASCII
)

func (GlyphProfile) Valid

func (profile GlyphProfile) Valid() bool

type GlyphSet

type GlyphSet struct {
	UserRail     string
	Collapsed    string
	Expanded     string
	Success      string
	Error        string
	Running      string
	Queued       string
	Waiting      string
	Cancelled    string
	Continuation string
	Selected     string
	Unselected   string
	Vertical     string
	Horizontal   string
	Left         string
	Right        string
}

GlyphSet is the semantic vocabulary shared by transcript, tools, agents, and controls. Every token below is one terminal cell in both profiles so swapping profiles cannot change layout geometry.

type GoalAction

type GoalAction string

GoalAction is emitted to the parent when a user selects a form action. The parent owns persistence and the goal lifecycle; GoalForm only collects and validates presentation state.

const (
	GoalActionNone   GoalAction = ""
	GoalActionSave   GoalAction = "save"
	GoalActionPause  GoalAction = "pause"
	GoalActionResume GoalAction = "resume"
	GoalActionClear  GoalAction = "clear"
	GoalActionCancel GoalAction = "cancel"
)

type GoalAdvisor

type GoalAdvisor interface {
	Open(context.Context, goaladvisor.OpenRequest) (goaladvisor.Advice, error)
	Status(context.Context, string) (goaladvisor.Advice, error)
}

GoalAdvisor is the semantic Cortex seam. Implementations may discover it directly or through MCPHub. Typed continuation suggestions are owned by the agent's exact registry/schema/policy interpreter, never this UI adapter.

type GoalDecisionAdvisor

type GoalDecisionAdvisor interface {
	AnswerDecision(context.Context, goaladvisor.AnswerDecisionRequest) (goaladvisor.Advice, error)
}

GoalDecisionAdvisor is optional so existing GoalAdvisor implementations and test fakes retain source compatibility. Answering is discovered only at the explicit confirmation boundary.

type GoalForm

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

GoalForm is a parent-routed, persistence-free inline component. It does not implement tea.Model: the application Model receives messages first and may forward them through Update, then decide what to do with GoalFormEvent.

func NewGoalForm

func NewGoalForm(initial GoalFormValues, options GoalFormOptions) *GoalForm

NewGoalForm creates a focused, responsive goal form. The zero options value defaults to an 80x24 canvas and Save/Cancel actions.

func (*GoalForm) ActiveField

func (f *GoalForm) ActiveField() GoalFormField

ActiveField returns the currently focused form step.

func (*GoalForm) BudgetOnly

func (f *GoalForm) BudgetOnly() bool

BudgetOnly reports whether the immutable goal definition is locked.

func (*GoalForm) Error

func (f *GoalForm) Error() string

Error returns the most recent inline validation or parent-owned semantic message.

func (*GoalForm) SetActiveField

func (f *GoalForm) SetActiveField(field GoalFormField) tea.Cmd

SetActiveField moves focus without changing any values.

func (*GoalForm) SetBudgetOnly

func (f *GoalForm) SetBudgetOnly(budgetOnly bool) tea.Cmd

SetBudgetOnly switches between new-goal editing and immutable-definition budget amendment. Locked definition fields remain visible but are skipped by focus and never receive input messages.

func (*GoalForm) SetChoices

func (f *GoalForm) SetChoices(choices ...GoalFormChoice)

SetChoices replaces the final action row. Blank choices are discarded and an empty result restores the safe Save/Cancel defaults.

func (*GoalForm) SetError

func (f *GoalForm) SetError(message string)

SetError presents a parent-owned semantic error without changing the user's values, focus, or selected action. The parent remains responsible for deciding whether an action is authorized; GoalForm only renders the feedback beside the action that was rejected.

func (*GoalForm) SetReducedMotion

func (f *GoalForm) SetReducedMotion(reduced bool)

SetReducedMotion replaces blinking cursors with static cursors. GoalForm never schedules decorative animation ticks of its own.

func (*GoalForm) SetSize

func (f *GoalForm) SetSize(width, height int)

SetSize adapts the cached form and its Bubbles inputs to the current canvas.

func (*GoalForm) SetTheme

func (f *GoalForm) SetTheme(isDark bool, themeID string)

SetTheme reapplies the project's LightDark-derived semantic palette.

func (*GoalForm) Update

func (f *GoalForm) Update(msg tea.Msg) (GoalFormEvent, tea.Cmd)

Update applies one parent-routed Bubble Tea message and emits a semantic action when appropriate. The returned command belongs in the parent's normal command batch so Bubbles cursor behavior remains cancellable.

func (*GoalForm) Values

func (f *GoalForm) Values() (GoalFormValues, error)

Values validates and returns the typed form payload.

func (*GoalForm) View

func (f *GoalForm) View() string

View renders the cached form without a hardware-cursor position.

func (*GoalForm) ViewWithCursor

func (f *GoalForm) ViewWithCursor() (string, *tea.Cursor)

ViewWithCursor renders the form and a cursor local to the returned frame. The parent translates it from the inline footer's origin.

type GoalFormChoice

type GoalFormChoice struct {
	Action            GoalAction
	Label             string
	Description       string
	RequiresValidGoal bool
	Destructive       bool
}

GoalFormChoice configures one action in the form's final focus step. RequiresValidGoal should be true for actions that create or update a goal.

type GoalFormEvent

type GoalFormEvent struct {
	Action GoalAction
	Values GoalFormValues
}

GoalFormEvent describes a user decision. GoalActionNone means the form only changed local presentation state.

type GoalFormField

type GoalFormField int

GoalFormField identifies one keyboard-focusable step in GoalForm.

const (
	GoalFieldObjective GoalFormField = iota
	GoalFieldAcceptance
	GoalFieldTurns
	GoalFieldTokens
	GoalFieldTime
	GoalFieldActions
)

type GoalFormOptions

type GoalFormOptions struct {
	Width         int
	Height        int
	IsDark        bool
	ThemeID       string
	ReducedMotion bool
	GlyphProfile  GlyphProfile
	// DraftFromPrompt tells the form that the initial definition was inferred
	// from the user's composer text. The draft remains fully editable.
	DraftFromPrompt bool
	// FollowUpPrompt replaces generic review copy when the inferred draft is
	// missing one concrete detail. It is guidance, not a validation error.
	FollowUpPrompt string
	// BudgetOnly locks the immutable objective and acceptance criteria while
	// preserving them as context for a budget amendment.
	BudgetOnly bool
	Choices    []GoalFormChoice
}

GoalFormOptions contains display preferences owned by the parent Model.

type GoalFormValues

type GoalFormValues struct {
	Objective          string
	AcceptanceCriteria string
	TurnBudget         int64
	TokenBudget        int64
	TimeBudget         time.Duration
}

GoalFormValues is the typed payload collected by GoalForm. A zero budget means no limit.

func (GoalFormValues) CriterionDescriptions

func (v GoalFormValues) CriterionDescriptions() []string

CriterionDescriptions returns the normalized, nonblank line items the parent can map to durable acceptance-criterion IDs.

type GoalInspector

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

GoalInspector is a read-only goal document plus a small action rail. A Bubbles viewport keeps the same information reachable at 30x12 without letting the modal grow beyond the terminal.

func NewGoalInspector

func NewGoalInspector(snapshot goal.Snapshot, actions []command.ActionState, options GoalInspectorOptions) *GoalInspector

NewGoalInspector creates a focused, persistence-free inspector.

func (*GoalInspector) CancelConfirmation

func (i *GoalInspector) CancelConfirmation() bool

CancelConfirmation consumes Escape only while a destructive action is armed. A second Escape is then owned by the parent and closes the modal.

func (*GoalInspector) SetReducedMotion

func (i *GoalInspector) SetReducedMotion(reduced bool)

SetReducedMotion records the shared accessibility preference. The inspector intentionally has no autonomous ticker, so selection remains deterministic.

func (*GoalInspector) SetSize

func (i *GoalInspector) SetSize(width, height int)

SetSize adapts both the document viewport and compact action grammar.

func (*GoalInspector) SetTheme

func (i *GoalInspector) SetTheme(isDark bool, themeID string)

SetTheme reapplies the project LightDark-derived semantic palette.

func (*GoalInspector) Update

Update handles presentation navigation only and returns intent to the smart parent. Destructive actions require a second explicit Enter receipt.

func (*GoalInspector) View

func (i *GoalInspector) View() string

View renders a cached modal frame. The viewport is only rebuilt when data, size, theme, or navigation changes.

type GoalInspectorEvent

type GoalInspectorEvent struct {
	ActionID command.ActionID
	Action   command.Action
}

GoalInspectorEvent asks the parent to execute one already-resolved command action. The child never mutates the goal runtime or persists session state.

type GoalInspectorOptions

type GoalInspectorOptions struct {
	Width            int
	Height           int
	IsDark           bool
	ThemeID          string
	ReducedMotion    bool
	GlyphProfile     GlyphProfile
	Now              time.Time
	PersistenceDirty bool
	RecoveryStatus   string
}

GoalInspectorOptions contains presentation-only host state. The durable snapshot and resolved actions remain immutable for the lifetime of a modal; the smart parent opens a fresh inspector after every lifecycle transition.

type GoalPhase

type GoalPhase string

GoalPhase is the lifecycle state displayed by RenderGoalStatusLine.

const (
	GoalPhaseActive    GoalPhase = "active"
	GoalPhasePaused    GoalPhase = "paused"
	GoalPhaseExhausted GoalPhase = "exhausted"
	GoalPhaseCompleted GoalPhase = "completed"
	GoalPhaseDropped   GoalPhase = "dropped"
	GoalPhaseBlocked   GoalPhase = "blocked"
)

type GoalRecovery

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

GoalRecovery is a Charm-native, persistence-free recovery wizard. The child owns focus and draft presentation only; it cannot inspect storage, mutate a goal, resume execution, or claim completion.

func NewGoalRecovery

func NewGoalRecovery(items []GoalRecoveryItem, options GoalRecoveryOptions) *GoalRecovery

NewGoalRecovery creates a focused recovery list. Zero dimensions default to an 80x24 canvas; SetSize keeps it responsive after construction.

func (*GoalRecovery) ActionableCount

func (r *GoalRecovery) ActionableCount() int

ActionableCount reports how many immutable items the parent explicitly marked safe to submit to its reconciliation service.

func (*GoalRecovery) Draft

func (r *GoalRecovery) Draft() GoalRecoveryDraft

Draft returns a copy of the current, unvalidated presentation draft.

func (*GoalRecovery) SelectedItem

func (r *GoalRecovery) SelectedItem() (GoalRecoveryItem, bool)

SelectedItem returns a copy of the selected immutable item.

func (*GoalRecovery) SetBusy

func (r *GoalRecovery) SetBusy(message string)

SetBusy marks a coordinator operation as in flight. Escape navigation stays available, but the wizard emits no second Apply event until the parent clears the state with an empty message.

func (*GoalRecovery) SetError

func (r *GoalRecovery) SetError(message string)

SetError attaches a bounded parent/coordinator failure to the active step. It never advances, closes, or clears the operator's draft.

func (*GoalRecovery) SetItems

func (r *GoalRecovery) SetItems(items []GoalRecoveryItem) tea.Cmd

SetItems replaces the parent's immutable projection while preserving the selected item identity when possible. A draft whose item disappeared is discarded and returned to the list rather than being retargeted.

func (*GoalRecovery) SetReducedMotion

func (r *GoalRecovery) SetReducedMotion(reduced bool)

SetReducedMotion replaces blinking Bubbles cursors with static cursors.

func (*GoalRecovery) SetSize

func (r *GoalRecovery) SetSize(width, height int)

SetSize adapts every Bubbles child to the current terminal canvas.

func (*GoalRecovery) SetTheme

func (r *GoalRecovery) SetTheme(isDark bool, themeID string)

SetTheme reapplies the existing LightDark-derived semantic palette.

func (*GoalRecovery) ShowRecordedReceipt

func (r *GoalRecovery) ShowRecordedReceipt(items []GoalRecoveryItem, notice string) tea.Cmd

ShowRecordedReceipt refreshes the immutable projection after a partial coordinator receipt, clears the now-consumed draft, and returns focus to the list. Persistence remains entirely parent-owned.

func (*GoalRecovery) Stage

func (r *GoalRecovery) Stage() GoalRecoveryStage

Stage reports the visible presentation step.

func (*GoalRecovery) Update

func (r *GoalRecovery) Update(msg tea.Msg) (GoalRecoveryEvent, tea.Cmd)

Update handles presentation messages routed by the smart parent and emits only Close or Apply intent. It never performs asynchronous work itself.

func (*GoalRecovery) View

func (r *GoalRecovery) View() string

View renders the cached modal without a hardware cursor.

func (*GoalRecovery) ViewWithCursor

func (r *GoalRecovery) ViewWithCursor() (string, *tea.Cursor)

ViewWithCursor renders the modal and a frame-local Bubble Tea cursor.

type GoalRecoveryAction

type GoalRecoveryAction string

GoalRecoveryAction is a presentation intent, never a lifecycle mutation.

const (
	GoalRecoveryActionNone  GoalRecoveryAction = ""
	GoalRecoveryActionClose GoalRecoveryAction = "close"
	GoalRecoveryActionApply GoalRecoveryAction = "apply"
)

type GoalRecoveryDraft

type GoalRecoveryDraft struct {
	Observation GoalRecoveryObservation
	Source      GoalRecoverySource
	Summary     string
	Reference   string
}

GoalRecoveryDraft is the bounded presentation payload emitted to the smart parent. The parent remains responsible for scope checks, evidence encoding, persistence, and every Goal Runtime transition.

type GoalRecoveryEvent

type GoalRecoveryEvent struct {
	Action GoalRecoveryAction
	ItemID string
	Draft  GoalRecoveryDraft
}

GoalRecoveryEvent asks the parent either to close the overlay or apply one validated draft to the exact immutable item. An empty Action is a local-only presentation update.

type GoalRecoveryItem

type GoalRecoveryItem struct {
	ItemID      string
	Kind        GoalRecoveryItemKind
	Subject     string
	Summary     string
	Tool        string
	ExecutionID string
	TurnID      string
	EventType   string
	EffectClass string
	Age         string
	Actionable  bool
	// DisabledReason is shown when the coordinator supplied an observational
	// parent/group item that cannot yet produce a reconciliation request.
	DisabledReason string
}

GoalRecoveryItem is a sanitized, immutable presentation projection supplied by the smart parent. It deliberately contains no payload or raw tool arguments. GoalRecovery copies every item and never mutates one.

type GoalRecoveryItemKind

type GoalRecoveryItemKind string

GoalRecoveryItemKind keeps turn-level authority distinct from exact execution-effect evidence. The coordinator, not the UI, assigns this kind.

const (
	GoalRecoveryExecutionEffect GoalRecoveryItemKind = "execution_effect"
	GoalRecoveryTurnBoundary    GoalRecoveryItemKind = "turn_boundary"
)

type GoalRecoveryObservation

type GoalRecoveryObservation string

GoalRecoveryObservation records what the operator observed. Still unknown is a safe navigation choice, not evidence and never reaches an apply event.

const (
	GoalRecoveryEffectApplied                GoalRecoveryObservation = "effect_applied"
	GoalRecoveryEffectNotApplied             GoalRecoveryObservation = "effect_not_applied"
	GoalRecoveryEffectCompensated            GoalRecoveryObservation = "effect_compensated"
	GoalRecoveryTurnAbandonedAfterInspection GoalRecoveryObservation = "turn_abandoned_after_inspection"
	GoalRecoveryStillUnknown                 GoalRecoveryObservation = "still_unknown"
)

type GoalRecoveryOptions

type GoalRecoveryOptions struct {
	Width         int
	Height        int
	IsDark        bool
	ThemeID       string
	ReducedMotion bool
	GlyphProfile  GlyphProfile
	// Standalone adapts the already-designed evidence review for an ordinary
	// goal-less session. Persistence and authority remain parent-owned.
	Standalone bool
}

GoalRecoveryOptions contains presentation-only host preferences.

type GoalRecoverySource

type GoalRecoverySource string

GoalRecoverySource describes the evidence locator without carrying backend authority or claiming that the execution ledger completed.

const (
	GoalRecoveryExternalReceipt     GoalRecoverySource = "external_receipt"
	GoalRecoveryWorkspaceArtifact   GoalRecoverySource = "workspace_artifact"
	GoalRecoveryVerificationCheck   GoalRecoverySource = "verification_check"
	GoalRecoveryOperatorObservation GoalRecoverySource = "operator_observation"
)

type GoalRecoveryStage

type GoalRecoveryStage int

GoalRecoveryStage identifies the currently visible step. Stages are exposed so the parent can describe focus without inspecting child internals.

const (
	GoalRecoveryStageList GoalRecoveryStage = iota
	GoalRecoveryStageObservation
	GoalRecoveryStageSource
	GoalRecoveryStageSummary
	GoalRecoveryStageReference
	GoalRecoveryStageConfirmation
)

type GoalSummary

type GoalSummary struct {
	Objective   string
	Phase       GoalPhase
	TurnsUsed   int64
	TurnBudget  int64
	TokensUsed  int64
	TokenBudget int64
	Elapsed     time.Duration
	TimeBudget  time.Duration
}

GoalSummary contains only the presentation data needed by the compact goal line. Zero budgets are omitted rather than presented as misleading limits.

type HeightClass

type HeightClass uint8

HeightClass is the vertical density tier for a terminal frame. Recovery is the zero value so an unmeasured terminal fails safe.

const (
	HeightRecovery HeightClass = iota
	HeightCompact
	HeightShort
	HeightRegular
	HeightTall
)

func ClassifyHeight

func ClassifyHeight(height int) HeightClass

ClassifyHeight maps a terminal height to its vertical density tier.

type HitRegion

type HitRegion struct {
	Rect     CellRect
	Z        int
	ActionID command.ActionID
	Target   EntityRef
	// contains filtered or unexported fields
}

HitRegion is one exact half-open cell rectangle in a rendered action projection. order is assigned by HitRegionSet and models paint order.

func (HitRegion) Order

func (region HitRegion) Order() uint64

Order returns the deterministic insertion order used to break equal-Z hits.

func (HitRegion) Request

func (region HitRegion) Request() UIActionRequest

Request returns the same typed request used by keyboard activation.

type HitRegionSet

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

HitRegionSet owns the pointer projection for one rendered frame. The zero value is ready to use; callers should rebuild it whenever layout changes.

func (*HitRegionSet) Add

func (set *HitRegionSet) Add(rect CellRect, z int, actionID command.ActionID, target EntityRef) bool

Add appends an exact hit rectangle. Empty or malformed regions fail closed.

func (*HitRegionSet) Hit

func (set *HitRegionSet) Hit(x, y int) (UIActionRequest, bool)

Hit resolves one terminal cell to the visually top-most request. Higher Z wins; within the same Z the most recently painted region wins.

func (*HitRegionSet) Regions

func (set *HitRegionSet) Regions() []HitRegion

Regions returns a copy in paint order.

func (*HitRegionSet) Reset

func (set *HitRegionSet) Reset()

Reset removes all regions and restarts paint order for a fresh frame.

type ImageAttachmentResultMsg

type ImageAttachmentResultMsg struct {
	Token     uint64
	Preflight bool
	Name      string
	Ref       imageasset.Ref
	Image     llm.ImageData
	Fallback  string
	Err       error
}

ImageAttachmentResultMsg completes one tokened asynchronous image admission. Fallback is reserved for explicit single-file callers; terminal PasteMsg image lists deliberately leave it empty so source paths never become prompt or session text after an admission failure.

type ImportResultMsg

type ImportResultMsg struct {
	Token          uint64
	Path           string
	Entries        []ChatEntry
	Messages       []llm.Message
	UIOnlySections int
	ToolSections   int
	Err            error
}

ImportResultMsg completes a bounded asynchronous /import operation. Parsing is done off the BubbleTea update loop so a large valid transcript cannot freeze rendering.

type InitCompleteMsg

type InitCompleteMsg struct {
	Model                    string
	ModelList                []string
	OllamaModels             []OllamaModelDescriptor
	OllamaVersion            string
	OllamaInventoryAttempted bool
	AgentProfile             string
	AgentList                []string
	ToolCount                int
	ServerCount              int
	NumCtx                   int
	FailedServers            []FailedServer
	MCPServers               []MCPServerStatus
	ICEEnabled               bool
	ICEConversations         int
	ICESessionID             string
}

InitCompleteMsg signals startup is done.

type Insets

type Insets struct {
	Top    int
	Right  int
	Bottom int
	Left   int
}

Insets reserves terminal cells along the four edges of a CellRect. Negative values are treated as zero.

type KeyHelpSection

type KeyHelpSection struct {
	Title    string
	Bindings []key.Binding
}

KeyHelpSection is a titled group of bindings.

The title lives here rather than in the help renderer because this is where the grouping decision belongs: a binding added to a section is documented under that heading automatically, and a renderer cannot invent a category the keymap disagrees with.

type KeyMap

type KeyMap struct {
	Send              key.Binding
	NewLine           key.Binding
	Cancel            key.Binding
	Quit              key.Binding
	ClearView         key.Binding
	NewConvo          key.Binding
	Help              key.Binding
	ToggleTools       key.Binding
	PageUp            key.Binding
	PageDown          key.Binding
	HalfPageUp        key.Binding
	HalfPageDn        key.Binding
	JumpLatest        key.Binding
	Complete          key.Binding
	CompleteUp        key.Binding
	CompleteDown      key.Binding
	CompleteToggle    key.Binding
	CompleteSelect    key.Binding
	CopyLast          key.Binding
	ToggleMouse       key.Binding
	Paste             key.Binding
	InspectOutput     key.Binding
	InspectDiff       key.Binding
	CycleMode         key.Binding
	ModelPicker       key.Binding
	SettingsPicker    key.Binding
	TranscriptSearch  key.Binding
	HistoryUp         key.Binding
	HistoryDown       key.Binding
	ToggleFocusedTool key.Binding
	VoiceInput        key.Binding
	ToggleThinking    key.Binding
	CompactToggle     key.Binding
	ExternalEditor    key.Binding
}

KeyMap defines all keyboard shortcuts for the application.

func DefaultKeyMap

func DefaultKeyMap() KeyMap

DefaultKeyMap returns the default keybindings.

func (KeyMap) FullHelp

func (k KeyMap) FullHelp() [][]key.Binding

FullHelp satisfies the Bubbles help.KeyMap interface. It is derived from HelpSections so the two cannot describe different key surfaces.

func (KeyMap) HelpSections

func (k KeyMap) HelpSections() []KeyHelpSection

HelpSections groups every binding by the task a reader is trying to do.

The help overlay used to print all twenty-six as one undifferentiated list, which meant finding "how do I search the transcript" was a linear scan past every editing and paging key. Sections are ordered by how often a reader needs them, not alphabetically or by keystroke.

func (KeyMap) ShortHelp

func (k KeyMap) ShortHelp() []key.Binding

ShortHelp returns the key groups for the short help view.

type LayoutCapabilities

type LayoutCapabilities struct {
	WorkRect   CellRect
	WorkWidth  int
	WorkHeight int
	ProseWidth int

	WidthClass  WidthClass
	HeightClass HeightClass
	Density     LayoutDensity

	CanDockContext      bool
	CanShowRichHeader   bool
	CanShowDiffGutters  bool
	CanShowDualGutters  bool
	CanUseSplitDiff     bool
	CanStackAuxiliary   bool
	CanShowAgentPreview bool
}

LayoutCapabilities is the immutable geometry contract for one component. WorkRect must be the component's final allocated rectangle, after parent splits and insets. Every width capability is calculated from residual work cells rather than from the outer terminal width.

func DeriveLayoutCapabilities

func DeriveLayoutCapabilities(workRect CellRect, options LayoutCapabilityOptions) LayoutCapabilities

DeriveLayoutCapabilities measures the final work rectangle for a component. The fixed numbers below are named design tokens. In particular, diff and split decisions require the minimum readable code width to remain after gutters and gaps have been subtracted.

type LayoutCapabilityOptions

type LayoutCapabilityOptions struct {
	ForceCompact bool
}

LayoutCapabilityOptions contains explicit user presentation preferences. ForceCompact changes density, but not the component's measured capacity.

type LayoutDensity

type LayoutDensity uint8

LayoutDensity is a presentation choice made after measuring a component. It must not be used as a substitute for a physical capability check.

const (
	LayoutDensityCompact LayoutDensity = iota
	LayoutDensityRegular
	LayoutDensitySpacious
)

type LineMap

type LineMap []TranscriptLinePoint

LineMap is ordered lexicographically by LogicalOffset then Grapheme, with non-decreasing rendered rows.

type MCPServerStatus

type MCPServerStatus struct {
	Name      string
	Connected bool
	ToolCount int
	Detail    string
}

MCPServerStatus is a bounded presentation snapshot. Detail is transient UI context only and is sanitized again when it enters Model state; it must never be copied into persisted transcript or session state.

type MCPStatusSnapshotMsg

type MCPStatusSnapshotMsg struct {
	Servers []MCPServerStatus
}

MCPStatusSnapshotMsg replaces the previous cached MCP presentation state. The registry health monitor emits it after connection-state transitions.

type MarkdownRenderer

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

MarkdownRenderer handles markdown rendering with caching support.

func NewMarkdownRenderer

func NewMarkdownRenderer(width int, isDark bool, themeID string) *MarkdownRenderer

NewMarkdownRenderer creates a renderer for the given terminal width and theme.

func (*MarkdownRenderer) RenderFull

func (mr *MarkdownRenderer) RenderFull(content string) string

RenderFull renders a complete markdown document (for finished messages). This is the "format-on-complete" path used when streaming ends.

func (*MarkdownRenderer) RenderStreaming

func (mr *MarkdownRenderer) RenderStreaming(content string) string

RenderStreaming renders content during streaming (plain text, no Glamour). This avoids jitter from re-rendering incomplete markdown.

func (*MarkdownRenderer) RenderStreamingFormatted

func (mr *MarkdownRenderer) RenderStreamingFormatted(content string) (formatted, tail string)

RenderStreamingFormatted renders in-progress content using the stable-prefix technique: the portion of the document up to the last safe markdown boundary (a blank line not inside an open code fence) is rendered with Glamour and cached; the trailing partial paragraph is returned separately to be shown as plain text. This makes streaming look formatted instead of "popping" into shape on completion, without the jitter of re-rendering incomplete markdown.

func (*MarkdownRenderer) SetWidth

func (mr *MarkdownRenderer) SetWidth(width int)

SetWidth updates the renderer for a new terminal width.

type ModalInstance

type ModalInstance struct {
	ID     OverlayID
	Kind   ModalKind
	Origin EntityRef
}

ModalInstance is the payload-free identity of one stacked viewer.

func (ModalInstance) FocusToken

func (modal ModalInstance) FocusToken() FocusToken

FocusToken returns the root focus identity for modal.

func (ModalInstance) Valid

func (modal ModalInstance) Valid() bool

Valid reports whether modal can safely enter the stack.

type ModalKind

type ModalKind uint8

ModalKind identifies the new viewer family hosted by ModalStack.

const (
	ModalKindUnknown ModalKind = iota
	ModalKindOutputViewer
	ModalKindDiffViewer
)

func (ModalKind) Valid

func (kind ModalKind) Valid() bool

Valid reports whether kind is a supported stacked viewer.

type ModalStack

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

ModalStack manages nested viewer identity and focus restoration. Bubble Tea's smart parent remains responsible for child Update and View calls.

func (*ModalStack) Clear

func (stack *ModalStack) Clear(fallback FocusToken) ([]ModalInstance, FocusToken)

Clear removes the entire chain in visual dismissal order (top first) and restores the focus captured before the bottom modal opened.

func (*ModalStack) Empty

func (stack *ModalStack) Empty() bool

Empty reports whether the stack has no active viewer.

func (*ModalStack) Len

func (stack *ModalStack) Len() int

Len returns the number of stacked modal viewers.

func (*ModalStack) Pop

func (stack *ModalStack) Pop(fallback FocusToken) (ModalInstance, FocusToken, bool)

Pop removes the active modal and returns the live focus destination. When a parent modal remains it always owns focus; after the last modal closes, a stale restoration token falls back to fallback and finally the composer.

func (*ModalStack) Projection

func (stack *ModalStack) Projection() OverlayProjection

Projection returns the active top modal and current stack depth.

func (*ModalStack) Push

func (stack *ModalStack) Push(modal ModalInstance, currentFocus FocusToken) error

Push adds modal and records the focus destination active before it opened. Invalid or stale modal focus falls back to the current top modal, then the composer.

func (*ModalStack) Replace

func (stack *ModalStack) Replace(modal ModalInstance) (ModalInstance, error)

Replace swaps the active modal at the same depth and preserves the original restoration chain. An identity already used lower in the stack is rejected.

func (*ModalStack) Top

func (stack *ModalStack) Top() (ModalInstance, bool)

Top returns the active modal without exposing stack storage.

type Mode

type Mode int

Mode represents the conversational preset selected in the TUI. Durable goal execution is an explicit, separate lifecycle entered through /goal.

const (
	ModeNormal Mode = iota // Interactive work with approval-gated mutations.
	ModePlan               // Read-only exploration and planning.
	ModeAuto               // Proactive work with full tools and configured approvals.
)

type ModeConfig

type ModeConfig struct {
	Label               string
	SystemPromptPrefix  string
	ToolPolicy          agent.ToolPolicy
	PreferredCapability config.ModelCapability
	RouterMode          config.ModeContext
}

ModeConfig holds the configuration for a single mode.

func DefaultModeConfigs

func DefaultModeConfigs() [3]ModeConfig

DefaultModeConfigs returns the configuration for each mode.

type ModePickerState

type ModePickerState struct {
	List list.Model
}

type Model

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

Model is the BubbleTea model for the chat interface.

func New

func New(ag *agent.Agent, cmdReg *command.Registry, skillMgr *skill.Manager, completer *Completer, modelManager *llm.ModelManager, router config.ModelRouter, logger *log.Logger) *Model

New creates a new TUI Model.

func (*Model) AnchorActive

func (m *Model) AnchorActive() bool

AnchorActive returns true if scroll anchor is active. Exported for testing.

func (*Model) Init

func (m *Model) Init() tea.Cmd

func (*Model) Ready

func (m *Model) Ready() bool

Ready returns true if the TUI is fully initialized. Exported for testing.

func (*Model) ReleaseExecutionSessionLease

func (m *Model) ReleaseExecutionSessionLease() error

ReleaseExecutionSessionLease releases the cross-process ownership held by the active interactive session. The main program calls it after Bubble Tea has joined the current turn and before SQLite closes.

func (*Model) SessionResumeInfo

func (m *Model) SessionResumeInfo() (SessionResumeInfo, bool)

SessionResumeInfo returns the active session's canonical short handle when the model owns a session backed by the durable store. It is read-only and is intended for the successful interactive-exit message.

func (*Model) SetAgentProfileSource

func (m *Model) SetAgentProfileSource(agentsDir *config.AgentsDir, baseLoadedContext, activeProfile string)

func (*Model) SetApprovalPosture

func (m *Model) SetApprovalPosture(posture ApprovalPosture)

SetApprovalPosture projects the host's actual permission posture into the TUI. Invalid values fail closed to the ordinary prompted posture. When an agent is attached, AcceptWorkspaceEdits is mirrored onto the agent so NORMAL write/edit/mkdir auto-approval stays process-local and consistent.

func (*Model) SetConfigSourcePath

func (m *Model) SetConfigSourcePath(path string)

SetConfigSourcePath records the resolved host config path so /context save can rewrite ollama.num_ctx without scanning for config files again.

func (*Model) SetGoalAdvisor

func (m *Model) SetGoalAdvisor(advisor GoalAdvisor)

SetGoalAdvisor wires Cortex after the parent has built the MCP registry. It is safe to call before MCP startup; tool discovery happens per operation.

func (*Model) SetImageStore

func (m *Model) SetImageStore(store *imageasset.Store)

SetImageStore installs the private attachment store and the Agent resolver used to rehydrate path-free image references after session/checkpoint restore. It must be called before the Bubble Tea program starts.

func (*Model) SetInitCancel

func (m *Model) SetInitCancel(cancel context.CancelFunc)

SetInitCancel stores the cancel function for the background init goroutine.

func (*Model) SetModelPinned

func (m *Model) SetModelPinned(pinned bool)

SetModelPinned preserves an explicit CLI or agent-profile model selection. Automatic routing remains available after the user runs /model auto.

func (*Model) SetModelPreferenceStore

func (m *Model) SetModelPreferenceStore(store ModelPreferenceStore)

SetModelPreferenceStore enables restart persistence for explicit /model, /provider, and picker selections. Startup flags and agent profiles remain separate runtime authorities and are never written through this store.

func (*Model) SetModelRoutingCatalog

func (m *Model) SetModelRoutingCatalog(models []config.Model)

SetModelRoutingCatalog installs the host-owned manual-only model policy used by later asynchronous Ollama inventory refreshes. Availability still comes exclusively from Ollama; this catalog can only remove automatic-routing authority from a discovered local model.

func (*Model) SetProgram

func (m *Model) SetProgram(p *tea.Program)

SetProgram sets the tea.Program reference (must be called before Run).

func (*Model) SetSessionStore

func (m *Model) SetSessionStore(store *db.Store)

SetSessionStore enables private SQLite-backed, lossless session resume.

func (*Model) SetStartupSessionResume

func (m *Model) SetStartupSessionResume(selector SessionResumeSelector) error

SetStartupSessionResume schedules one validated restore after InitComplete. It never starts provider work and shares the interactive picker's tokened restore authority.

func (*Model) SetTheme

func (m *Model) SetTheme(id string) bool

SetTheme selects the color scheme and rebuilds every cached style. It returns false for an unregistered id so a caller can report the typo instead of silently repainting in the default.

func (*Model) SetVoiceInput added in v0.7.0

func (m *Model) SetVoiceInput(cfg config.VoiceInputConfig)

SetVoiceInput installs dictation settings. Dictation needs no enable flag of its own: the key does nothing until pressed, and pressing it on a host without the tools says which one to install rather than failing quietly.

func (*Model) StartVoice added in v0.6.0

func (m *Model) StartVoice(cfg config.VoiceConfig) string

StartVoice installs a speaker when the operator asked for one and the host has a synthesizer, and returns a notice to print when voice was requested and cannot be delivered.

A request the host cannot honour is reported rather than silently dropped: someone who enabled voice and hears nothing should be told which of the two halves is missing.

func (*Model) ThemeID

func (m *Model) ThemeID() string

ThemeID reports the active color scheme.

func (*Model) Update

func (m *Model) Update(msg tea.Msg) (retModel tea.Model, retCmd tea.Cmd)

func (*Model) View

func (m *Model) View() tea.View

type ModelPickerState

type ModelPickerState struct {
	List      list.Model
	Models    []config.Model // compatibility projection for existing callers
	Inventory []OllamaModelDescriptor
	// CatalogModels is set when the picker was built from the provider catalog
	// rather than a local inventory. The two are mutually exclusive.
	CatalogModels []catalog.Model
	CurrentModel  string
	RequestID     uint64
	Notice        string
	Compact       bool
	ItemHeight    int
}

func (*ModelPickerState) SelectedCatalogModel

func (s *ModelPickerState) SelectedCatalogModel() (catalog.Model, bool)

SelectedCatalogModel returns the highlighted catalog model, if the picker is catalog-backed and something is highlighted.

func (*ModelPickerState) SelectedDescriptor

func (s *ModelPickerState) SelectedDescriptor() (OllamaModelDescriptor, bool)

func (*ModelPickerState) SelectedReason

func (s *ModelPickerState) SelectedReason() string

type ModelPreferenceStore

type ModelPreferenceStore interface {
	SetManualModel(string) error
	ClearManualModel() error
	SetManualProvider(string) error
	ClearManualProvider() error
	SetTheme(string) error
}

ModelPreferenceStore is the narrow user-runtime persistence boundary for a manually selected model and optional provider profile. It is intentionally independent from session state.

type OllamaModelDescriptor

type OllamaModelDescriptor struct {
	Name             string
	DisplayName      string
	Source           OllamaModelSource
	SizeBytes        int64
	ParameterSize    string
	Quantization     string
	ContextLength    int
	EffectiveContext int
	AllocatedContext int
	SizeVRAM         int64
	Capabilities     []string
	Current          bool
	Running          bool
	Selectable       bool
	Fit              bool
	AutoRoutable     bool
	ManualOnly       bool
	Reason           string
}

OllamaModelDescriptor is the UI-facing inventory contract. The Ollama adapter owns discovery and enrichment; the picker only projects that state.

func BuildOllamaModelDescriptors

func BuildOllamaModelDescriptors(
	models []llm.OllamaModel,
	running []llm.OllamaRunningModel,
	currentModel string,
	_ bool,
) []OllamaModelDescriptor

BuildOllamaModelDescriptors projects a locally discovered inventory into picker descriptors.

Transitional. The admission logic this replaced encoded local-runtime concerns — memory fit, VRAM residency, automatic-routing eligibility, and Ollama Cloud consent — none of which describe a model reached over an API. Every discovered model is now simply selectable, and the catalog-driven picker will supersede this projection entirely.

type OllamaModelInventoryMsg

type OllamaModelInventoryMsg struct {
	RequestID uint64
	Models    []OllamaModelDescriptor
	Err       error
}

OllamaModelInventoryMsg replaces the picker's cached inventory. RequestID lets the parent discard stale asynchronous refreshes.

type OllamaModelSource

type OllamaModelSource uint8

OllamaModelSource is the execution boundary reported by Ollama. It is kept in the UI package so the picker does not depend on a particular wire client.

const (
	OllamaModelLocal OllamaModelSource = iota
	OllamaModelCloud
	OllamaModelRemote
)

type OutputDetailCursor

type OutputDetailCursor struct {
	Row        int
	ByteOffset int
}

OutputDetailCursor addresses a byte offset within one retained logical row. ByteOffset is needed because a single row may exceed the 64 KiB page budget.

type OutputDetailDigest

type OutputDetailDigest struct {
	TotalRows     uint64 `json:"total_rows"`
	RetainedRows  uint64 `json:"retained_rows"`
	TotalBytes    uint64 `json:"total_bytes"`
	RetainedBytes uint64 `json:"retained_bytes"`
	Truncated     bool   `json:"truncated"`
}

OutputDetailDigest is the only durable shape associated with full output. Counts describe terminal-safe UTF-8 after control-sequence sanitization. Total counts cover the complete sanitized source; retained counts cover the bounded prefix that may be paged during this process.

func (OutputDetailDigest) Valid

func (digest OutputDetailDigest) Valid() bool

Valid treats a decoded digest as untrusted scalar input. It accepts the useful zero shape, rejects impossible row/byte relationships, and enforces the production retention caps without granting loadability.

type OutputDetailPage

type OutputDetailPage struct {
	Rows    []OutputDetailRow
	Next    OutputDetailCursor
	HasMore bool
	Bytes   uint64
	Digest  OutputDetailDigest
}

OutputDetailPage contains only terminal-safe retained content. Next is valid when HasMore is true. Bytes counts Text bytes in Rows; newline delimiters are represented by row boundaries and therefore are not charged twice.

type OutputDetailPageRequest

type OutputDetailPageRequest struct {
	Ref       OutputDetailRef
	Cursor    OutputDetailCursor
	RowLimit  int
	ByteLimit int
}

OutputDetailPageRequest asks for a bounded page. Non-positive limits select the store defaults; larger limits are clamped to the hard page maxima.

type OutputDetailReceipt

type OutputDetailReceipt struct {
	Ref    OutputDetailRef    `json:"-"`
	Digest OutputDetailDigest `json:"digest"`
}

OutputDetailReceipt pairs the ephemeral load capability with its persistable scalar digest. Artifact digests are intentionally not accepted by this store: knowing that an artifact exists does not grant output loadability.

type OutputDetailRef

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

OutputDetailRef is an opaque, process-local capability for one admitted output. Its identity is intentionally unexported, so encoding a bare ref cannot persist or disclose the capability. Fields that carry one must still use json:"-" to make the ephemeral ownership explicit.

func (OutputDetailRef) MarshalJSON

func (ref OutputDetailRef) MarshalJSON() ([]byte, error)

MarshalJSON makes the non-persistence contract explicit even when a caller encodes a bare ref outside OutputDetailReceipt. A capability can never be reconstructed from the resulting empty object.

func (OutputDetailRef) String

func (ref OutputDetailRef) String() string

String returns the opaque identity for in-process diagnostics and equality assertions. It must not be written to a session or transcript.

func (OutputDetailRef) Valid

func (ref OutputDetailRef) Valid() bool

Valid reports whether ref has the bounded shape issued by this package. A valid shape is not proof that the store still owns the referenced output.

type OutputDetailRow

type OutputDetailRow struct {
	Index             int
	Text              string
	StartsMidRow      bool
	EndsRow           bool
	SourceRowComplete bool
}

OutputDetailRow is one whole row or one UTF-8-safe fragment of a giant row. EndsRow means the fragment reaches the retained row boundary. SourceRowComplete additionally distinguishes a complete source row from the final partial row produced by source truncation.

type OutputDetailStore

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

OutputDetailStore owns bounded full-output prefixes for the lifetime of the active UI. Entries are immutable after admission; the mutex protects the map, aggregate byte accounting, and LRU order.

func NewOutputDetailStore

func NewOutputDetailStore() *OutputDetailStore

NewOutputDetailStore constructs a process-local store with the fixed production budgets documented above.

func (*OutputDetailStore) Admit

func (store *OutputDetailStore) Admit(raw string) (OutputDetailReceipt, error)

Admit sanitizes raw before retaining any bytes, records honest counts for the complete sanitized source, then admits only its bounded prefix.

func (*OutputDetailStore) Available

func (store *OutputDetailStore) Available(ref OutputDetailRef) bool

Available reports whether the store still owns ref. A valid reference shape is not sufficient because LRU eviction and explicit revocation are normal. This method never reveals content or refreshes recency.

func (*OutputDetailStore) Drop

func (store *OutputDetailStore) Drop(ref OutputDetailRef) bool

Drop revokes one ephemeral ref and releases its retained bytes.

func (*OutputDetailStore) Len

func (store *OutputDetailStore) Len() int

Len reports the current number of live ephemeral refs.

func (*OutputDetailStore) Page

Page resolves one process-local ref into a bounded UTF-8-safe page. Unknown, stale, and evicted refs fail closed without a partial page. Cancellation is checked before lookup, during construction, and immediately before return.

func (*OutputDetailStore) RetainedBytes

func (store *OutputDetailStore) RetainedBytes() uint64

RetainedBytes reports the conservative aggregate memory charge used by the global budget. It includes source bytes, the compact row-offset index, and a fixed allowance for the entry, ref, map, and LRU bookkeeping.

type OutputViewer

type OutputViewer struct {
	Origin  EntityRef
	Receipt OutputDetailReceipt
	// contains filtered or unexported fields
}

OutputViewer is a one-page, presentation-only full-output inspector. It retains an ephemeral receipt but never a store, context, clipboard callback, transcript pointer, or raw tool payload.

func NewOutputViewer

func NewOutputViewer(
	origin EntityRef,
	receipt OutputDetailReceipt,
	width, height int,
	isDark bool,
	profiles ...GlyphProfile,
) *OutputViewer

NewOutputViewer creates an isolated viewer. The caller starts page loading by forwarding InitialPageRequest to the smart parent.

func (*OutputViewer) Anchor

func (viewer *OutputViewer) Anchor() OutputViewerAnchor

Anchor returns the first visible semantic source row.

func (*OutputViewer) ApplyPage

func (viewer *OutputViewer) ApplyPage(token OutputViewerPageToken, page OutputDetailPage) bool

ApplyPage is the successful-result convenience form.

func (*OutputViewer) ApplyPageError

func (viewer *OutputViewer) ApplyPageError(token OutputViewerPageToken, err error) bool

ApplyPageError is the failed-result convenience form.

func (*OutputViewer) ApplyPageResult

func (viewer *OutputViewer) ApplyPageResult(
	token OutputViewerPageToken,
	page OutputDetailPage,
	err error,
) bool

ApplyPageResult settles only the exact current request token. Any error, invalid projection, unavailable/evicted ref, or digest mismatch fails closed to the same non-actionable state without exposing transport details.

func (*OutputViewer) CachedRowCount

func (viewer *OutputViewer) CachedRowCount() int

CachedRowCount exposes only the cache cardinality for diagnostics and tests. Output content remains private to the viewer.

func (*OutputViewer) InitialPageRequest

func (viewer *OutputViewer) InitialPageRequest() OutputViewerEvent

InitialPageRequest emits the first bounded request exactly once. Repeated calls while a request is pending or after a result has settled are no-ops.

func (*OutputViewer) Layout

func (viewer *OutputViewer) Layout() OutputViewerLayout

Layout returns the current immutable geometry snapshot.

func (*OutputViewer) ReplaceReceipt

func (viewer *OutputViewer) ReplaceReceipt(receipt OutputDetailReceipt) OutputViewerEvent

ReplaceReceipt starts a fresh generation while keeping the same semantic origin and modal instance. Late results from the previous receipt cannot mutate the replacement page.

func (*OutputViewer) SetReducedMotion

func (viewer *OutputViewer) SetReducedMotion(reduced bool)

SetReducedMotion keeps the search input static for users who disable animation. It changes only cursor presentation; semantic focus, query, geometry, and source-row position remain stable.

func (*OutputViewer) SetSize

func (viewer *OutputViewer) SetSize(width, height int)

SetSize reprojects geometry while preserving the first visible source row.

func (*OutputViewer) SetTheme

func (viewer *OutputViewer) SetTheme(isDark bool, themeID string)

SetTheme changes adaptive presentation styles without moving the semantic source-row anchor.

func (*OutputViewer) Status

func (viewer *OutputViewer) Status() OutputViewerStatus

Status returns the viewer's current presentation state.

func (*OutputViewer) Update

func (viewer *OutputViewer) Update(msg tea.Msg) (OutputViewerEvent, tea.Cmd)

Update handles Bubbles presentation messages and returns typed intent for its smart parent. It performs no page IO, clipboard writes, transcript mutation, or modal-stack mutation.

func (*OutputViewer) View

func (viewer *OutputViewer) View() string

View renders an exact-size modal frame and intentionally drops the optional child hardware cursor. Parents that route focus should use ViewWithCursor.

func (*OutputViewer) ViewWithCursor

func (viewer *OutputViewer) ViewWithCursor() (string, *tea.Cursor)

ViewWithCursor returns one cursor at most, local to the rendered frame. It is present only while the search Bubbles input owns focus.

type OutputViewerAnchor

type OutputViewerAnchor struct {
	SourceRow int
	Valid     bool
}

OutputViewerAnchor names the first visible source row rather than a presentation offset. Resizing, theme changes, and search-row insertion may all change viewport geometry without changing this semantic anchor.

type OutputViewerEvent

type OutputViewerEvent struct {
	Kind     OutputViewerEventKind
	Origin   EntityRef
	Token    OutputViewerPageToken
	Request  OutputDetailPageRequest
	CopyText string
}

OutputViewerEvent is a bounded child-to-parent intent. CopyText contains only the currently visible, terminal-safe output cells; it is never written to the transcript by this component.

func (OutputViewerEvent) Empty

func (event OutputViewerEvent) Empty() bool

Empty reports whether no intent was emitted.

type OutputViewerEventKind

type OutputViewerEventKind uint8

OutputViewerEventKind identifies the only intents a presentation-only OutputViewer may emit. The smart parent owns page IO, clipboard integration, and modal-stack mutation.

const (
	OutputViewerEventNone OutputViewerEventKind = iota
	OutputViewerEventRequestPage
	OutputViewerEventCopyVisible
	OutputViewerEventClose
)

type OutputViewerLayout

type OutputViewerLayout struct {
	ScreenRect  CellRect
	OuterRect   CellRect
	ContentRect CellRect
	HeaderRect  CellRect
	SearchRect  CellRect
	BodyRect    CellRect
	FooterRect  CellRect
}

OutputViewerLayout is the exact screen-space geometry used for both rendering and pointer routing. All rectangles are half-open.

func ProjectOutputViewerLayout

func ProjectOutputViewerLayout(screenWidth, screenHeight int, searchVisible bool) OutputViewerLayout

ProjectOutputViewerLayout computes a centered modal whose preferred extent is 90% of the terminal, with a 72x12 floor that always clamps back to the actual screen. One border cell and one horizontal padding cell are deducted before assigning the header, optional search row, body, and footer.

type OutputViewerPageToken

type OutputViewerPageToken struct {
	Generation uint64
	Sequence   uint64
}

OutputViewerPageToken fences asynchronous page results by both viewer generation and request sequence. A token is intentionally scalar: the process-local output capability remains in OutputDetailPageRequest.

func (OutputViewerPageToken) Valid

func (token OutputViewerPageToken) Valid() bool

Valid reports whether the token can identify one page request.

type OutputViewerStatus

type OutputViewerStatus uint8

OutputViewerStatus is the presentation state of the one-page cache.

const (
	OutputViewerLoading OutputViewerStatus = iota
	OutputViewerReady
	OutputViewerUnavailable
)

type OverlayID

type OverlayID string

OverlayID is a bounded opaque identity for a modal surface. It is separate from the legacy OverlayKind enum: OverlayID identifies one instance while OverlayKind identifies a legacy presentation category.

func (OverlayID) Valid

func (id OverlayID) Valid() bool

Valid reports whether id is a bounded, terminal-safe opaque identity.

type OverlayKind

type OverlayKind int

OverlayKind represents what overlay (if any) is currently shown.

const (
	OverlayNone OverlayKind = iota
	OverlayHelp
	OverlayCompletion
	OverlayModelPicker
	OverlayPlanForm
	OverlayCortexDecision
	OverlaySessionsPicker
	OverlaySettings
	OverlayAgentPicker
	OverlayProviderPicker
	OverlayModePicker
	OverlayGoalForm
	OverlayRuntimeStatus
	OverlayGoalInspector
	OverlayGoalRecovery
	OverlayTranscriptSearch
	OverlayPermissions
	OverlayThemePicker
	OverlayContextDoctor
	OverlaySubagents
)

type OverlayProjection

type OverlayProjection struct {
	Active bool
	Depth  int
	Top    ModalInstance
	Focus  FocusToken
}

OverlayProjection is the complete scalar state needed to compose and route the top stacked modal. Legacy overlays remain outside this projection.

type PermissionsPanelState

type PermissionsPanelState struct {
	List       list.Model
	ItemHeight int
	Compact    bool
}

PermissionsPanelState is a transient list of posture, session grants, and durable workspace rules. The parent Model owns every side effect.

type PlanFormCompletedMsg

type PlanFormCompletedMsg struct {
	Prompt string
}

PlanFormCompletedMsg signals the plan form has been submitted with a structured prompt.

type PlanFormField

type PlanFormField struct {
	Label       string
	Kind        string   // "text" or "select"
	Value       string   // current value (for select, set from Options[OptionIndex])
	Options     []string // for "select" kind
	OptionIndex int      // for "select" kind
	Input       textinput.Model
}

PlanFormField represents a single field in the plan form.

type PlanFormState

type PlanFormState struct {
	Fields      []PlanFormField
	ActiveField int
	// contains filtered or unexported fields
}

PlanFormState holds state for the composer-owned plan form.

func NewPlanFormState

func NewPlanFormState(task string, themeID string, presentation ...bool) *PlanFormState

NewPlanFormState creates a plan form pre-filled with the user's task description. Presentation options are ordered as theme-dark, then reduced-motion so older callers that only select a theme remain source compatible.

func (*PlanFormState) AssemblePrompt

func (pf *PlanFormState) AssemblePrompt() string

AssemblePrompt builds the structured prompt from form fields.

type PromptPathPreflightResultMsg

type PromptPathPreflightResultMsg struct {
	Token                  uint64
	Draft                  string
	Grants                 []agent.ReadGrant
	WriteGrants            []agent.WriteGrant
	UnavailableWrites      []string
	Authority              Mode
	MoreCandidates         bool
	CandidateLimitExceeded bool
}

PromptPathPreflightResultMsg carries canonical host projections plus opaque preview identities owned by Agent. Missing, workspace-local, non-regular and already-authorized candidates are omitted by the background inspector.

type ProviderCredentialState

type ProviderCredentialState uint8
const (
	ProviderCredentialNotRequired ProviderCredentialState = iota
	ProviderCredentialReady
	ProviderCredentialMissing
)

type ProviderLocality

type ProviderLocality uint8
const (
	ProviderLocal ProviderLocality = iota
	ProviderRemote
)

type ProviderOptionPresentation

type ProviderOptionPresentation struct {
	ProfileID      ProviderProfileID
	Label          string
	KindLabel      string
	ModelLabel     string
	Locality       ProviderLocality
	Credential     ProviderCredentialState
	CredentialHint string
	Active         bool
	Selectable     bool
	DisabledReason string
}

ProviderOptionPresentation is the complete provider-picker boundary. It deliberately has no BaseURL, client, header, credential value, or arbitrary configuration field.

type ProviderPickerState

type ProviderPickerState struct {
	List        list.Model
	ItemHeight  int
	ItemSpacing int
}

ProviderPickerState is the Bubbles list for /provider.

type ProviderProfileID

type ProviderProfileID string

ProviderProfileID is an opaque catalog identity. It is used only to route a selection back to the model manager and is never rendered directly.

type ReadScopePreviewResultMsg

type ReadScopePreviewResultMsg struct {
	Token     uint64
	Requested string
	Canonical string
	Workspace string
	Draft     string
	Grant     agent.ReadGrant
	Err       error
}

ReadScopePreviewResultMsg completes canonicalization and read-only boundary checks before the user is asked to authorize an external root.

type ReadScopePrompt

type ReadScopePrompt struct {
	Requested   string
	Canonical   string
	Workspace   string
	Draft       string
	Kind        agent.ReadGrantKind
	Grants      []agent.ReadGrant
	WriteGrants []agent.WriteGrant
	Operation   string
	AutoResume  bool
}

ReadScopePrompt is transient presentation authority for canonicalized external paths. It is never serialized into session state.

type ReadScopeResultMsg

type ReadScopeResultMsg struct {
	Token       uint64
	Operation   string
	Path        string
	Kind        string
	Count       int
	Grants      []agent.ReadGrant
	WriteGrants []agent.WriteGrant
	AutoResume  bool
	RolledBack  int
	RollbackErr error
	Err         error
	// Rollback and Finalize are process-local transaction handles. They never
	// enter transcript/session state; Update consumes exactly one of them.
	Rollback func() (int, error)
	Finalize func()
}

ReadScopeResultMsg completes one process-local external read-root change. The Agent remains the authority for canonicalization and overlap checks.

type RuntimeStatusState

type RuntimeStatusState struct {
	Viewport viewport.Model
}

type ScrambleModel

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

ScrambleModel is a custom BubbleTea component that renders a gradient character scramble animation, inspired by Charmbracelet's Crush CLI.

func NewScrambleModel

func NewScrambleModel(isDark bool, themeID string) ScrambleModel

NewScrambleModel creates a new scramble animation with theme-appropriate colors.

func (*ScrambleModel) Reset

func (s *ScrambleModel) Reset()

Reset resets the animation (new ID + zero visible). Call when agent starts.

func (*ScrambleModel) SetDark

func (s *ScrambleModel) SetDark(isDark bool, themeID string)

SetDark repoints the gradient at the active scheme.

The endpoints used to be four literal hexes, and the dark pair was Nord's Accent and a purple close to its Accent2 — so the wait animation painted Nord on every scheme. Switching to Catppuccin or Gruvbox left this one surface behind, which is the whole failure the theme registry exists to prevent, and the comment here already claimed to interpolate "the active theme's colors".

Accent → Accent2 is the correct pair by meaning, not by resemblance: the gradient reads as one signal travelling out and coming back, which is the two-accent relationship every scheme already answers.

func (ScrambleModel) Tick

func (s ScrambleModel) Tick() tea.Cmd

Tick schedules the next animation frame (~15 FPS = 66ms).

func (ScrambleModel) Update

func (s ScrambleModel) Update(msg tea.Msg) (ScrambleModel, tea.Cmd)

Update processes tick messages and advances the animation.

func (ScrambleModel) View

func (s ScrambleModel) View() string

View renders the complete visible animation.

func (ScrambleModel) ViewN

func (s ScrambleModel) ViewN(maxCells int) string

ViewN renders at most maxCells of the animation. The parent uses a single animated cell on narrow terminals and the full six-cell shimmer when space permits, keeping the working action visible at every supported width.

type ScrambleTickMsg

type ScrambleTickMsg struct {
	ID    int
	Frame int
}

ScrambleTickMsg triggers the next animation frame.

type SemanticAnchor

type SemanticAnchor struct {
	SessionID     int64
	BlockID       BlockID
	TurnID        TurnID
	LogicalOffset int
	Grapheme      int
	ScreenRow     int
	Bias          AnchorBias
}

SemanticAnchor identifies a logical point inside a block and the viewport row where the reader expects that point to remain. TurnID is retained for a deterministic turn-start fallback if the block is deleted.

type SessionListItem

type SessionListItem struct {
	ID        int64  `json:"id"`
	PublicID  string `json:"public_id,omitempty"`
	Title     string `json:"title"`
	CreatedAt string `json:"created_at"`
}

SessionListItem represents a session in the list.

type SessionListMsg

type SessionListMsg struct {
	ListToken uint64
	Sessions  []SessionListItem
	Err       error
}

SessionListMsg delivers the list of saved SQLite sessions.

type SessionLoadedMsg

type SessionLoadedMsg struct {
	LoadToken        uint64
	SessionID        int64
	SessionPublicID  string
	State            persistedSessionState
	StateRecord      db.SessionStateRecord
	Title            string
	RecoveryWarning  string
	RecoveryTarget   *agent.UnresolvedExecutionError
	RecoveryContexts []db.StandaloneReconciliationContext
	ExecutionLease   *db.ExecutionSessionLease
	Err              error
}

SessionLoadedMsg delivers a persisted session and its execution lease.

type SessionProviderIdentity

type SessionProviderIdentity struct {
	Profile string
	Remote  bool
}

SessionProviderIdentity is the bounded provider provenance attached to a headless session snapshot. Remote is explicit so a session created through an OpenAI-compatible adapter can never be restored under a same-named local model (or vice versa) merely because the model strings happen to match.

type SessionResumeInfo

type SessionResumeInfo struct {
	Handle string
	Title  string
}

SessionResumeInfo is the bounded durable identity shown by the CLI after Bubble Tea restores the terminal. Title is sanitized display metadata only; Handle remains the sole input to the canonical resume command.

type SessionResumeSelector

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

SessionResumeSelector identifies one exact saved session or the newest session in the canonical current workspace. Its fields are closed so callers must pass through the validated constructors below.

func ParseSessionResumeSelector

func ParseSessionResumeSelector(value string) (SessionResumeSelector, error)

ParseSessionResumeSelector parses the value accepted by --resume.

func SessionIDResumeSelector

func SessionIDResumeSelector(id int64) (SessionResumeSelector, error)

SessionIDResumeSelector constructs the exact-ID form used by the interactive picker after its database-backed list selection.

type SessionsPickerState

type SessionsPickerState struct {
	List     list.Model
	Sessions []SessionListItem
	Phase    sessionsPickerPhase
	Message  string
}

SessionsPickerState holds state for the sessions picker overlay.

type SettingsPickerState

type SettingsPickerState struct {
	List       list.Model
	ItemHeight int
	Compact    bool
}

SettingsPickerState is the transient control center that replaces the persistent navigation chrome. It contains list/navigation and responsive presentation state only; the parent Model owns and applies every setting.

type ShutdownMsg

type ShutdownMsg struct{}

ShutdownMsg requests a graceful stop. Active turns are cancelled and joined before BubbleTea exits so dispatched effects receive a final receipt.

type StartupStatusMsg

type StartupStatusMsg struct {
	ID     string // unique key: "ollama", "mcp:<name>", "ice"
	Label  string // display name: "Ollama (qwen3:8b)", "docker-gateway"
	Status string // "connecting", "connected", "failed"
	Detail string // e.g. "110 tools", error message
}

StartupStatusMsg reports progress of a single startup task (Ollama, MCP server, ICE).

type State

type State int

State represents the TUI's two possible states.

const (
	StateIdle      State = iota // waiting for user input
	StateWaiting                // sent to LLM, waiting for first token
	StateStreaming              // LLM is generating a response
)

type StreamDoneMsg

type StreamDoneMsg struct {
	EvalCount    int
	PromptTokens int
}

StreamDoneMsg signals the LLM has finished responding.

type StreamTextMsg

type StreamTextMsg struct {
	Text string
}

StreamTextMsg delivers incremental text from the LLM.

type StreamThinkingMsg

type StreamThinkingMsg struct{ Text string }

StreamThinkingMsg carries provider-native reasoning separately from answer text.

type Styles

type Styles struct {

	// Messages
	UserContent lipgloss.Style
	UserGutter  lipgloss.Style

	// Tools
	ToolErrorText   lipgloss.Style
	ToolRunningText lipgloss.Style

	// Footer
	Divider        lipgloss.Style
	StatusDot      lipgloss.Style
	StatusText     lipgloss.Style
	StatusCheck    lipgloss.Style
	StatusError    lipgloss.Style
	StatusWarning  lipgloss.Style
	ApprovalPrompt lipgloss.Style
	StreamHint     lipgloss.Style
	ErrorText      lipgloss.Style
	ErrorChip      lipgloss.Style
	Dimmed         lipgloss.Style

	// System messages
	WelcomeHint lipgloss.Style

	// Completion modal
	CompletionFilter   lipgloss.Style
	CompletionCategory lipgloss.Style

	// Startup progress
	StartupDetail lipgloss.Style

	// Mode badges
	ModeAsk   lipgloss.Style
	ModePlan  lipgloss.Style
	ModeBuild lipgloss.Style

	// Context percentage fuel gauge
	ContextPctLow  lipgloss.Style
	ContextPctMid  lipgloss.Style
	ContextPctHigh lipgloss.Style

	// Diff view
	DiffAdded   lipgloss.Style
	DiffRemoved lipgloss.Style
	DiffContext lipgloss.Style
	DiffHeader  lipgloss.Style

	// Thinking display
	ThinkingHeader  lipgloss.Style
	ThinkingContent lipgloss.Style
	ThinkingBorder  lipgloss.Style

	// Shared overlay styles (used by help, model picker, sessions, plan form, completion)
	OverlayTitle  lipgloss.Style
	OverlayBorder color.Color
	OverlayAccent lipgloss.Style
	OverlayDim    lipgloss.Style

	// Focus indicators
	FocusIndicator lipgloss.Style
}

Styles holds all pre-built lipgloss styles.

func NewStyles

func NewStyles(isDark bool, themeID string) Styles

NewStyles creates a Styles set based on the background color.

type SubagentsPanelState added in v0.12.0

type SubagentsPanelState struct {
	Viewport viewport.Model
	Selected int
}

The subagents view is the switcher the feature exists for: every child on one screen, the selected child's activity and answer-so-far underneath — present tense while it runs, the settled answer once it stops. It reads live Agent snapshots on every rebuild, so "live" is nothing more than a repaint tick while the view is open. It owns the whole screen, like the voice stage, rather than sitting in a modal over a conversation nobody is reading meanwhile.

Selection and scroll deliberately use different axes (←/→ switches a child, ↑/↓ and page keys scroll its transcript) so switching children — the whole point — never fights reading one of them.

type SystemMessageMsg

type SystemMessageMsg struct {
	Msg string
}

SystemMessageMsg displays a system-level message.

type Theme

type Theme struct {
	ID          string
	Label       string
	Description string
	Light       themeColors
	Dark        themeColors
}

A Theme is a named pair of semantic color vocabularies, one for a light terminal and one for a dark terminal.

Themes do not introduce new color meanings. semanticPalette remains the only vocabulary the components speak, so adding a theme is a matter of answering the same eleven questions in a different palette — never of teaching a component about a specific scheme.

Every value here is checked by TestThemeForegroundsMeetContrastInBothModes, which measures each foreground against that theme's own background. Where an upstream scheme publishes only a dark variant, or publishes a light variant whose accents fall below 4.5:1 on its light surface, the values are deliberately darkened versions of the same hues rather than the upstream hex. That adaptation is noted per theme; it is the same treatment the built-in Nord palette has always had.

type ThemePickerState

type ThemePickerState struct {
	List       list.Model
	ItemHeight int
}

ThemePickerState is the transient color-scheme chooser. It holds navigation state only; the parent Model owns the selection and its persistence.

func (*ThemePickerState) SelectedThemeID

func (s *ThemePickerState) SelectedThemeID() string

SelectedThemeID returns the highlighted theme.

type ToolApprovalMsg

type ToolApprovalMsg struct {
	RequestID       string
	ToolName        string
	Args            map[string]any
	ArgumentsSHA256 string
	Preview         permission.ApprovalPreview
	Scope           permission.ApprovalScope
	Response        chan<- permission.ApprovalResponse
}

ToolApprovalMsg asks the user to approve a tool call.

type ToolCallResultMsg

type ToolCallResultMsg struct {
	ID           string
	Name         string
	Result       string
	IsError      bool
	Duration     time.Duration
	Projection   ecosystem.ToolProjection
	OutputDetail OutputDetailReceipt
}

ToolCallResultMsg delivers the result of a tool call.

type ToolCallStartMsg

type ToolCallStartMsg struct {
	ID                      string
	Name                    string
	Args                    map[string]any
	StartTime               time.Time
	BeforeContent           string
	BeforeSnapshotAvailable bool
}

ToolCallStartMsg signals a tool invocation has begun.

type ToolCard

type ToolCard struct {
	ID      string
	Name    string
	Kind    ToolCardKind
	State   ToolCardState
	Summary string
	Args    string
	Result  string
	// ResultDisplay is a transient display-only variant of Result, retained
	// only when the raw tool output carried ANSI escapes. It is re-rendered
	// through remapANSI16Line and must never be persisted or written to the
	// terminal directly; the sanitized Result stays the only durable copy.
	ResultDisplay string

	// ResultLanguage is a bounded lexer alias derived from trusted host metadata
	// while the tool call is active. It never contains a path or result bytes.
	ResultLanguage string
	// OutputDigest is the scalar, persistable description of the original
	// terminal-safe output. OutputAvailable grants no access by itself; it only
	// reports whether the parent still owns a process-local viewer capability.
	OutputDigest    OutputDetailDigest
	OutputAvailable bool
	PreviewMode     ToolPreviewMode
	StartTime       time.Time
	Duration        time.Duration
	Expanded        bool
	IsDark          bool
	ThemeID         string
	GlyphProfile    GlyphProfile
	Lifecycle       ToolLifecycle
	Projection      ecosystem.ToolProjection
	Styles          ToolCardStyles
	// contains filtered or unexported fields
}

ToolCard is a fancy tool execution display component.

func NewToolCard

func NewToolCard(name string, kind ToolCardKind, isDark bool, themeID string, profiles ...GlyphProfile) ToolCard

NewToolCard creates a new tool card.

func ToolCardFromRenderModel

func ToolCardFromRenderModel(model ToolRenderModel, isDark bool, themeID string, profiles ...GlyphProfile) (ToolCard, error)

ToolCardFromRenderModel constructs the dumb visual component exclusively from the strict render projection. It never reads ToolEntry or Model state.

func (*ToolCard) SetDark

func (c *ToolCard) SetDark(isDark bool, themeID string)

SetDark updates the theme.

func (*ToolCard) SetSummary

func (c *ToolCard) SetSummary(summary string)

SetSummary stores a bounded, single-line semantic summary for compact and running headers. Callers should prefer this over assigning Summary directly; rendering applies the same bound defensively either way.

func (ToolCard) View

func (c ToolCard) View(width int) string

View renders a stable card suitable for completed receipts, cached transcript content, and tests. Running cards use a static activity glyph and intentionally omit live elapsed time; the smart parent can provide both via ViewWithActivity.

func (ToolCard) ViewWithActivity

func (c ToolCard) ViewWithActivity(width int, activityGlyph string, elapsed time.Duration) string

ViewWithActivity renders without mutating card state. The smart parent owns animation and elapsed-time updates and may pass one shared activity glyph plus an explicit elapsed duration for a running card.

type ToolCardKind

type ToolCardKind int

ToolCardKind represents the type of tool operation.

const (
	ToolCardFile ToolCardKind = iota
	ToolCardBash
	ToolCardSearch
	ToolCardGit
	ToolCardGeneric
)

type ToolCardState

type ToolCardState int

ToolCardState represents the execution state.

const (
	ToolCardRunning ToolCardState = iota
	ToolCardSuccess
	ToolCardAttention
	ToolCardError
)

type ToolCardStyles

type ToolCardStyles struct {
	BorderRunning   lipgloss.Style
	BorderSuccess   lipgloss.Style
	BorderAttention lipgloss.Style
	BorderError     lipgloss.Style
	TitleRunning    lipgloss.Style
	TitleSuccess    lipgloss.Style
	TitleAttention  lipgloss.Style
	TitleError      lipgloss.Style
	Args            lipgloss.Style
	Result          lipgloss.Style
	Error           lipgloss.Style
	Warning         lipgloss.Style
	Dimmed          lipgloss.Style
	Elapsed         lipgloss.Style
	DiffAdded       lipgloss.Style
	DiffRemoved     lipgloss.Style
	DiffHeader      lipgloss.Style
	SearchPath      lipgloss.Style
	SearchLocation  lipgloss.Style
	SearchMatch     lipgloss.Style
}

ToolCardStyles holds styles for the tool card.

func NewToolCardStyles

func NewToolCardStyles(isDark bool, themeID string) ToolCardStyles

NewToolCardStyles creates styles based on theme.

type ToolEntry

type ToolEntry struct {
	ID                      string
	Name                    string
	Summary                 string         // bounded semantic context for compact/restored receipts
	Args                    string         // formatted args string
	RawArgs                 map[string]any `json:"-"` // ephemeral original args
	Result                  string
	ResultDisplay           string `json:"-"` // transient raw-ANSI display variant for render-time remap; never persisted or restored
	ResultLanguage          string // bounded lexer alias derived from trusted call metadata
	OutputDetail            OutputDetailReceipt
	IsError                 bool
	Status                  ToolStatus
	StartTime               time.Time
	Duration                time.Duration
	Collapsed               bool                     // per-entry collapse state
	BeforeContent           string                   `json:"-"` // ephemeral snapshot before file write
	BeforeSnapshotAvailable bool                     `json:"-"` // false when the bounded pre-write read was unavailable
	DiffLines               []DiffLine               // computed diff (nil = not a file write)
	DiffPending             bool                     `json:"-"` // post-write read/LCS is running outside Update
	DiffGeneration          uint64                   `json:"-"` // accepts exactly one matching asynchronous result
	Projection              ecosystem.ToolProjection // bounded semantic role, route, and outcome
}

ToolEntry tracks the lifecycle of a single tool call.

type ToolKind

type ToolKind uint8

ToolKind is the provider-neutral semantic family of one invocation. It is deliberately independent from card styling and transcript geometry.

const (
	ToolKindUnknown ToolKind = iota
	ToolKindFile
	ToolKindShell
	ToolKindSearch
	ToolKindGit
	ToolKindGeneric
)

func (ToolKind) Valid

func (kind ToolKind) Valid() bool

type ToolLifecycle

type ToolLifecycle uint8

ToolLifecycle describes the user-visible lifecycle without conflating a successful transport with a successful domain operation.

const (
	ToolLifecycleUnknown ToolLifecycle = iota
	ToolLifecyclePending
	ToolLifecycleRunning
	ToolLifecycleSucceeded
	ToolLifecycleAttention
	ToolLifecycleFailed
	ToolLifecycleCancelled
)

func (ToolLifecycle) Terminal

func (lifecycle ToolLifecycle) Terminal() bool

func (ToolLifecycle) Valid

func (lifecycle ToolLifecycle) Valid() bool

type ToolPreview

type ToolPreview struct {
	Mode            ToolPreviewMode
	Arguments       string
	Result          string
	ResultLanguage  string
	OutputDigest    OutputDetailDigest
	OutputAvailable bool
	StartedAt       time.Time
	Expanded        bool
	DiffLines       []DiffLine
	DiffPending     bool
	// contains filtered or unexported fields
}

ToolPreview is the bounded, terminal-safe body admitted to a tool card. RawArgs, BeforeContent, provider StructuredContent, and arbitrary metadata intentionally have no representation here.

type ToolPreviewMode

type ToolPreviewMode uint8

ToolPreviewMode selects a bounded result-body policy without exposing raw arguments or asking the visual component to infer semantics from a provider-controlled name.

const (
	ToolPreviewUnknown ToolPreviewMode = iota
	ToolPreviewRead
	ToolPreviewExec
	ToolPreviewSearch
	ToolPreviewEdit
	ToolPreviewGeneric
)

func (ToolPreviewMode) Valid

func (mode ToolPreviewMode) Valid() bool

type ToolRenderModel

type ToolRenderModel struct {
	ToolViewModel
	Preview ToolPreview
}

ToolRenderModel is the only production input to tool rendering. ToolEntry remains the durable lifecycle state; this strict projection is rebuilt at the transcript boundary and ToolCard stays a dumb, ephemeral component.

func ToolRenderModelFromEntry

func ToolRenderModelFromEntry(chat ChatEntry, entry ToolEntry) (ToolRenderModel, error)

ToolRenderModelFromEntry is the strict production adapter from transcript state into tool UI. Every copied body field is bounded and sanitized here; ephemeral arguments/snapshots and raw MCP StructuredContent cannot cross because ToolPreview has no fields capable of retaining them.

func (ToolRenderModel) Validate

func (model ToolRenderModel) Validate() error

Validate rejects any preview that did not pass through the strict bounded constructor. It intentionally checks values rather than trusting callers in the ui package because restored state is attacker-controlled input.

type ToolStatus

type ToolStatus int

ToolStatus represents the state of a tool execution.

const (
	ToolStatusRunning ToolStatus = iota
	ToolStatusDone
	ToolStatusError
	ToolStatusCancelled
)

type ToolType

type ToolType int

ToolType represents the category of a tool for rendering.

const (
	ToolTypeDefault ToolType = iota
	ToolTypeBash
	ToolTypeFileRead
	ToolTypeFileWrite
	ToolTypeSearch
	ToolTypeWeb
	ToolTypeMemory
)

type ToolViewModel

type ToolViewModel struct {
	InvocationID string
	BlockID      BlockID
	ToolName     string
	Kind         ToolKind
	Operation    string
	Target       string
	Lifecycle    ToolLifecycle
	Transport    ecosystem.TransportState
	Domain       ecosystem.DomainState
	Evidence     ecosystem.EvidenceState
	Summary      string
	Duration     time.Duration
	Revision     uint64
	Artifact     *ecosystem.ArtifactDigest
	// Projection is already normalized by internal/ecosystem and contains only
	// bounded routing, digest, artifact, and semantic-state facts. It is kept so
	// the dumb ToolCard can render specialist receipts without reaching back
	// into ToolEntry or raw provider output.
	Projection ecosystem.ToolProjection
}

ToolViewModel is the narrow, terminal-safe projection admitted to tool UI. Raw arguments, results, MCP StructuredContent, provider prose, and layout state have no representation here.

func ToolViewModelFromToolCard

func ToolViewModelFromToolCard(chat ChatEntry, card ToolCard) (ToolViewModel, error)

ToolViewModelFromToolCard projects the card compatibility model through the same narrow boundary used by transcript tool entries.

func ToolViewModelFromToolEntry

func ToolViewModelFromToolEntry(chat ChatEntry, entry ToolEntry) (ToolViewModel, error)

ToolViewModelFromToolEntry projects one transcript tool block without carrying ToolEntry.Args, RawArgs, Result, ResultDisplay, or diff snapshots.

func (ToolViewModel) Validate

func (view ToolViewModel) Validate() error

Validate fails closed before a projected invocation enters transcript UI.

type TranscriptAnchor

type TranscriptAnchor struct {
	Mode   TranscriptAnchorMode
	Manual SemanticAnchor
}

TranscriptAnchor is a serializable sum type for follow/manual scroll intent. Manual is ignored while Mode is TranscriptAnchorFollowLatest.

func FollowLatestAnchor

func FollowLatestAnchor() TranscriptAnchor

FollowLatestAnchor constructs an anchor that follows the newest output.

func ManualTranscriptAnchor

func ManualTranscriptAnchor(anchor SemanticAnchor) TranscriptAnchor

ManualTranscriptAnchor constructs an anchor for a semantic reading point.

type TranscriptAnchorMode

type TranscriptAnchorMode uint8

TranscriptAnchorMode separates the intent to follow new output from a manually selected semantic reading position.

const (
	TranscriptAnchorFollowLatest TranscriptAnchorMode = iota
	TranscriptAnchorManual
)

type TranscriptAnchorResolution

type TranscriptAnchorResolution struct {
	Reason             AnchorResolutionReason
	BlockID            BlockID
	LocalRow           int
	MappedRow          int
	ViewportTop        int
	ScreenRow          int
	RequestedScreenRow int
	ContentClamped     bool
	ViewportClamped    bool
	LayoutExact        bool
}

TranscriptAnchorResolution is a pure projection into viewport coordinates. ViewportClamped explains a changed screen row at document boundaries; ContentClamped explains a missing exact line-map coordinate.

func ResolveTranscriptAnchor

func ResolveTranscriptAnchor(
	anchor TranscriptAnchor,
	previous TranscriptLayoutSnapshot,
	current TranscriptLayoutSnapshot,
	viewportHeight int,
) (TranscriptAnchorResolution, error)

ResolveTranscriptAnchor maps scroll intent into the current layout.

The previous layout is used only as an identity/order snapshot when a block was deleted. The fallback order is:

  • same block and semantic offset;
  • next surviving block when Bias is AnchorBiasNext;
  • previous surviving block;
  • first surviving block in the same turn;
  • document top.

AnchorBiasPrevious intentionally skips the next-block step.

type TranscriptBlock

type TranscriptBlock struct {
	ID        BlockID
	TurnID    TurnID
	ParentID  BlockID
	Kind      BlockKind
	Revision  uint64
	Lifecycle BlockLifecycle
	Payload   BlockPayload
}

TranscriptBlock is one semantic item in causal transcript order. Revision changes only when Payload or Lifecycle changes; layout and presentation changes must not increment it.

func (TranscriptBlock) MarshalJSON

func (TranscriptBlock) MarshalJSON() ([]byte, error)

MarshalJSON prevents the semantic runtime model from becoming an accidental persistence schema. A versioned durable DTO must select safe fields.

func (*TranscriptBlock) UnmarshalJSON

func (*TranscriptBlock) UnmarshalJSON([]byte) error

UnmarshalJSON prevents a manipulated or incomplete envelope from silently replacing private payload fields with a valid-looking zero value.

func (TranscriptBlock) Validate

func (block TranscriptBlock) Validate() error

Validate checks identity and state invariants that must hold before a block enters a transcript store or durable envelope.

type TranscriptLayoutRecord

type TranscriptLayoutRecord struct {
	BlockID  BlockID
	TurnID   TurnID
	Revision uint64
	Height   int
	StartRow int
	Exact    bool
	LineMap  LineMap
}

TranscriptLayoutRecord is the renderer-independent geometry required to restore an anchor. StartRow is validated as a contiguous prefix sum so the resolver cannot silently consume a stale or contradictory frame.

type TranscriptLayoutSnapshot

type TranscriptLayoutSnapshot struct {
	SessionID int64
	Records   []TranscriptLayoutRecord
}

TranscriptLayoutSnapshot binds a layout, including an empty layout, to one session. Session scope belongs to the snapshot rather than each record so a newly created or cleared conversation cannot lose its identity.

type TranscriptLinePoint

type TranscriptLinePoint struct {
	LogicalOffset int
	Grapheme      int
	Row           int
}

TranscriptLinePoint maps a stable logical text position to a rendered local row. LogicalOffset and Grapheme are semantic coordinates supplied by the block renderer; neither is a byte offset.

type TranscriptSearchState

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

TranscriptSearchState owns only an ephemeral index of text that has already crossed the transcript's safe presentation boundary. It deliberately has no field capable of retaining raw tool payloads, StructuredContent, or hidden reasoning.

type TurnID

type TurnID string

TurnID groups causally related blocks without making their slice position part of their identity.

func NewTurnID

func NewTurnID() (TurnID, error)

NewTurnID returns a process-independent 128-bit transcript turn identity.

func (TurnID) Valid

func (id TurnID) Valid() bool

Valid reports whether id is a bounded, canonical opaque identity.

type UIAction

type UIAction struct {
	ID       command.ActionID
	Label    string
	Shortcut key.Binding
	Enabled  bool
	Reason   string
	Target   EntityRef
}

UIAction is the bounded presentation and dispatch state of one action. It contains no function or arbitrary payload; the smart parent dispatches the accepted ActionID with a typed EntityRef.

func (UIAction) Request

func (action UIAction) Request(source UIActionSource) UIActionRequest

Request creates the common request used by keyboard and pointer paths.

type UIActionRegistry

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

UIActionRegistry keeps resolved actions in deterministic registration order. Re-registering an ID replaces its current state without moving its position. The zero value is ready to use.

func NewUIActionRegistry

func NewUIActionRegistry(actions ...UIAction) *UIActionRegistry

NewUIActionRegistry creates a registry and registers actions in argument order. Invalid actions are ignored, matching Register's fail-closed policy.

func (*UIActionRegistry) Action

func (registry *UIActionRegistry) Action(id command.ActionID) (UIAction, bool)

Action returns an isolated copy of one registered action.

func (*UIActionRegistry) Actions

func (registry *UIActionRegistry) Actions() []UIAction

Actions returns isolated action copies in stable registration order.

func (*UIActionRegistry) Register

func (registry *UIActionRegistry) Register(action UIAction) bool

Register adds or replaces one action. It returns false when the action cannot safely cross the UI dispatch boundary.

func (*UIActionRegistry) ResolveRequest

func (registry *UIActionRegistry) ResolveRequest(request UIActionRequest) (UIAction, string, bool)

ResolveRequest admits a keyboard or pointer request only when its action is still registered, enabled, and bound to the exact current target. The returned reason is suitable for a short status notice; unknown and malformed requests always fail closed.

type UIActionRequest

type UIActionRequest struct {
	ActionID command.ActionID
	Target   EntityRef
	Source   UIActionSource
}

UIActionRequest is the only dispatch request emitted by action surfaces.

type UIActionSource

type UIActionSource uint8

UIActionSource identifies the physical input path that requested an action. It does not affect authorization; both paths pass through ResolveRequest.

const (
	UIActionSourceUnknown UIActionSource = iota
	UIActionSourceKeyboard
	UIActionSourceMouse
)

func (UIActionSource) Valid

func (source UIActionSource) Valid() bool

Valid reports whether source is a supported user input path.

type UIActionSpec

type UIActionSpec struct {
	ID       command.ActionID
	Label    string
	Shortcut key.Binding
}

UIActionSpec is immutable presentation metadata for one stable action ID. Resolve supplies only current, scalar state and remains side-effect free.

func (UIActionSpec) Resolve

func (spec UIActionSpec) Resolve(target EntityRef, enabled bool, reason string) UIAction

Resolve projects a static action specification against current UI state.

type VoiceTranscriptMsg added in v0.7.0

type VoiceTranscriptMsg struct {
	Token uint64
	Text  string
	Err   error
}

VoiceTranscriptMsg carries a finished transcription back to the parent.

type WidthClass

type WidthClass uint8

WidthClass is the horizontal density tier for a terminal frame. Recovery is the zero value so an unmeasured terminal fails safe.

const (
	WidthRecovery WidthClass = iota
	WidthCompact
	WidthNarrow
	WidthRegular
	WidthWide
)

func ClassifyWidth

func ClassifyWidth(width int) WidthClass

ClassifyWidth maps a terminal width to its horizontal density tier.

Source Files

Jump to

Keyboard shortcuts

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