Documentation
¶
Overview ¶
Package status owns the v2 TUI's bottom HUD: the run-state pill, model + token cells, context-utilization meter, and the contextual hint line that sits above it.
The package exposes three pieces:
*State — the run-state machine that maps incoming agent events onto a coarse RunState enum. Sticky for terminal states (Error / IterLimit); cleared on submit.
*StatusBar — the rendering wrapper. Held by App; composes the HUD using the live State, Usage, context tokens, and theme.
HintProvider interface + default hint table. The App walks the focus stack to find the topmost provider; absent that, falls back to a RunState-keyed default. Lets overlays (M7+) hint without coupling to the status bar.
Index ¶
- func ContextLimitFor(model string) int
- func DefaultHint(s RunState) string
- func ResolveHint(state *State, focus HintProvider) string
- func SpinnerTickCmd() tea.Cmd
- type HintProvider
- type RunState
- type State
- func (s *State) Apply(e event.Event)
- func (s *State) Current() RunState
- func (s *State) Dismiss()
- func (s *State) Frame() int
- func (s *State) Hint() string
- func (s *State) OnRunDone(err error, interrupted bool)
- func (s *State) OnSubmit()
- func (s *State) SetHint(msg string)
- func (s *State) TickSpinner()
- type StatusBar
- func (s *StatusBar) Compose(width int, th *theme.Theme) string
- func (s *StatusBar) SetAgentID(id string)
- func (s *StatusBar) SetAgentName(name string)
- func (s *StatusBar) SetContext(used, limit int)
- func (s *StatusBar) SetEffort(level string)
- func (s *StatusBar) SetModel(m string)
- func (s *StatusBar) SetPermissionMode(mode string)
- func (s *StatusBar) SetUsage(u llm.Usage)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ContextLimitFor ¶
ContextLimitFor returns the model's context window from the constant.MODEL_CONTEXT_SIZE table, or 0 when unknown. Exposed as a package-level helper so the App can pass it through to SetContext without re-importing constant.
func DefaultHint ¶
DefaultHint returns the fallback hint for a RunState. The state's own override Hint (when set via SetHint) wins over this; this is the floor.
We intentionally don't promise features that aren't bound yet:
- Ctrl+Y yank → wired in M8
- Ctrl+F search → wired in M9
The strings here will be extended as those keys come online.
func ResolveHint ¶
func ResolveHint(state *State, focus HintProvider) string
ResolveHint picks the active hint string from three layered sources, in priority order:
- The state's override (set by App when a transient event needs to speak: "interrupted", "queued — will land at next iteration", "no controller attached"). Wins over everything.
- The provided focus HintProvider, if non-nil and yields a non-empty Hint().
- The RunState's default hint.
Either or both upstream sources may be nil — the function tolerates missing layers.
func SpinnerTickCmd ¶
SpinnerTickCmd returns a tea.Cmd that fires a SpinnerTickMsg after the theme's standard SpinnerInterval (100 ms). The App's Update handler returns another SpinnerTickCmd from the SpinnerTickMsg branch to keep the cycle going.
Types ¶
type HintProvider ¶
type HintProvider interface {
Hint() string
}
HintProvider is anything that can contribute a one-line contextual hint to the status row above the input. The App walks the focus stack to find the topmost provider; if none yields a non-empty string, the default hint table for the current RunState is used instead.
Future overlays (yank mode, search, permission) satisfy this interface so the status hint always reflects what keys the user can press right now.
type RunState ¶
type RunState int
RunState is the agent's high-level lifecycle from the UI's perspective. Drives the status-bar pill (label + color + spinner) and the contextual hint shown above the input.
const ( StateIdle RunState = iota StateRunning // generic "agent loop is alive between sub-phases" StateThinking // model is generating reasoning tokens StateTexting // model is generating response content tokens StateExecuting // a tool call is in flight StateDraining // pulling async subagent results back StateCompacting // micro/full session compaction running StateIterLimit // paused at the iter cap; Enter resumes StateError // terminal error from the last Run )
func (RunState) IsActive ¶
IsActive reports whether the state represents work-in-flight, i.e. the status pill should animate with the spinner rather than show a static glyph.
func (RunState) IsTerminal ¶
IsTerminal reports whether the state is sticky — won't be overwritten by a stray mid-run event. Used by Apply to guard transitions out of Error / IterLimit.
type State ¶
type State struct {
// contains filtered or unexported fields
}
State holds the live RunState plus the spinner frame index and an optional one-line hint message that overrides the default hint when set (e.g. "interrupted", "queued — will land at next iter").
Construct with NewState. Drive via Apply (for agent events), OnRunDone (when the Run goroutine returns), OnSubmit (when the user submits a prompt), and TickSpinner (on every spinnerTickMsg).
func (*State) Apply ¶
Apply advances State in response to one agent event. Mirrors v1's updateStateFromEvent: terminal states are sticky (no overwrite from a stray turn-end), mid-run transitions map onto the coarse sub-phase enum.
func (*State) Dismiss ¶
func (s *State) Dismiss()
Dismiss clears a terminal state — used by the Esc handler when state is Error (matches the "Esc dismiss" hint). No-op for active states.
func (*State) Hint ¶
Hint returns the override hint message (or "" when no override is set). Overrides win over the default hint table.
func (*State) OnRunDone ¶
OnRunDone transitions out of the running cluster based on the error returned by controller.Run. Mirrors v1's handleRunDone:
- nil err → idle
- "iteration limit" sentinel → iter-limit pause
- other err → error state
The caller passes an interrupted=true flag when the error came from a ctx.Cancel (Esc / Ctrl+C); we drop back to idle in that case and leave the hint for the App to display.
func (*State) OnSubmit ¶
func (s *State) OnSubmit()
OnSubmit transitions to StateRunning and clears any stale hint / terminal state. Called when the App kicks off controller.Run.
func (*State) SetHint ¶
SetHint installs (or clears) an override message. Cleared at the start of the next OnSubmit/OnRunDone so stale messages don't haunt future turns.
func (*State) TickSpinner ¶
func (s *State) TickSpinner()
TickSpinner advances the spinner frame by 1. Called from the App on every spinnerTickMsg.
type StatusBar ¶
type StatusBar struct {
// contains filtered or unexported fields
}
StatusBar holds the live HUD state and renders the bottom row of the screen. It's not a tea.Model in the strict sense — there's no Update method — because every input it needs flows through the App (state machine + usage + context tokens). It's a pure renderer.
func New ¶
New constructs a StatusBar bound to the given run-state machine. The bar reads State.Current() / State.Frame() on every Compose call, so any state transitions reflect on the next render without explicit notification.
func (*StatusBar) Compose ¶
Compose returns the rendered HUD as one styled line, padded to width. Layout (left → right):
‹⠋ STATE› ◆ EVVA ◆ ▸ model ◆ IN n OUT m ◆ CTX ▰▰▱…▱ pct ◆ SID 1234abcd
Each cell is separated by a violet diamond. Cells collapse when their underlying data is empty.
func (*StatusBar) SetAgentID ¶
SetAgentID stores the controller's agent id; rendered truncated to 8 chars. Empty input collapses the cell entirely.
func (*StatusBar) SetAgentName ¶
SetAgentName stores the active persona's display label (typically uppercased: "EVVA", "NONO"). Empty falls back to "EVVA" in Compose so the pre-attach state still renders something sensible.
func (*StatusBar) SetContext ¶
SetContext stores the prompt-token / context-limit pair used to drive the utilization meter. used is the input-token count from the most recent agent turn (Session.LastTurnInputTokens); limit is the model's context window from constant.MODEL_CONTEXT_SIZE.
func (*StatusBar) SetModel ¶
SetModel installs the model id shown in the status bar's model cell. Empty string collapses to "-".
func (*StatusBar) SetPermissionMode ¶
SetPermissionMode stores the active permission mode for the status bar cell. Empty string or "default" collapses the cell so the bar isn't cluttered for users in the default stance.