Documentation
¶
Overview ¶
Package station implements `muster station`, the operator TUI. Spec §5-LOCK (2026-07-17) is the operator-approved, locked design: pure STACK navigation (Enter pushes, Esc pops exactly one frame, g pops home), a mailbox as its own page, one canonical header-badge renderer, and an agent page with a header band (+ a marked-but-empty vitals slot, 0.6.1) above its full-width threads table. Like `muster watch`, station never streams — it polls the daemon on a tea.Tick, but the poll loop is owned by the Bubble Tea MODEL instead of a bare for-loop, so the event journal cursor advances only when the model actually applies an events page (see Update's eventsMsg branch) rather than whenever a fetch happens to complete.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FlagSet ¶ added in v0.7.0
FlagSet declares station's flags, exported so muster's CLI command registry (internal/humancli) can render `muster help station` / `muster station -h` and detect flag.ErrHelp before ever spinning up the full-screen TUI, without keeping a second, driftable copy of the flag list. Run below builds its OWN identical FlagSet rather than calling this one directly, because it needs typed *string/*bool/*int pointers back — keep the two declarations in sync if you touch either.
func Run ¶
Run parses station's flags, registers its tmux identity on the bus (collision-safe fail-over per spec §5), and runs the Bubble Tea program.
Exit does NOT deregister (spec iteration-8: "operator read-state survives restarts"). A prior version deregistered — conditionally but unconditionally-on-every-exit-path — which DELETED the agent row, including last_read_entry_id: the operator's own read watermark. That meant every station restart resurrected already-acknowledged mail as unread (an operator-diagnosed regression: "📬 2 came back" after a plain quit/relaunch). Leaving the row in place instead means: tmux-liveness (get_agent/list_agents' own liveness check, which shells to real tmux rather than trusting this row) correctly shows the row DEAD between runs — nothing here claims station is still live while it isn't — and the NEXT `muster station` launch's registerStation call re-registers the exact same alias, whose upsert (store.Store.RegisterAgent) already preserves last_read_entry_id verbatim (it simply isn't one of the columns the ON CONFLICT clause overwrites — see agents.go), so the operator's read watermark survives the restart intact.
The `muster gc` caveat noted in earlier revisions of this comment is resolved: gc's default reap now tombstones (DepartAgent, departed=1) instead of hard-deleting, so a dead station row — including its read watermark — survives gc exactly like a plain quit/relaunch. Only the explicit, opt-in `muster gc --purge-agents` still hard-deletes (the old behavior), which is an operator's deliberate choice, not gc's default.
Types ¶
type Model ¶
type Model struct {
// contains filtered or unexported fields
}
Model is the station Bubble Tea model. It owns the event journal cursor — Update's eventsMsg branch is the ONLY place it advances, and only after a page is actually applied.
func NewModel ¶
NewModel constructs a station Model against caller (the daemon-transport seam — production wraps internal/client.Call via daemonCaller, tests hand in a fake).
func (Model) Init ¶
Init issues the first poll immediately (so the screen isn't blank for a full --interval) and schedules the first tick. Since a fresh Model is not yet bootstrapped, that first poll's events fetch is pollCmd's backlog branch, not follow — see pollCmd and applyEvents.
type Options ¶
type Options struct {
Interval time.Duration // poll interval (--interval, default 1s)
Aliases bool // show raw aliases instead of labels (--aliases)
Width int // total line budget (--width; 0 = default)
Alias string // this station's own registered alias
Nudger nudger // test seam for the 'n' nudge action; nil (default) uses nudge.TmuxNudger{} (real tmux)
}
Options configures a Model — station.Run's flags, or whatever a test wants to fix directly.