station

package
v0.7.6 Latest Latest
Warning

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

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

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

func FlagSet() *flag.FlagSet

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

func Run(args []string) error

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

func NewModel(caller render.Caller, opts Options) Model

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

func (m Model) Init() tea.Cmd

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.

func (Model) Update

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

Update implements tea.Model. See eventsMsg/agentsMsg/threadsMsg handling below for the cursor discipline (identical to watch: max_id, regression reset, errors → status line + retry, never exit).

func (Model) View

func (m Model) View() string

View implements tea.Model.

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.

Jump to

Keyboard shortcuts

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