tui¶
Package tui provides terminal UI components built on Bubbletea.
The package owns two surfaces:
- The persistent applet (AppletModel et al. in applet*.go) — a full-screen Bubbletea program that mirrors the Fyne GUI's workspace list, detail, settings, and create views.
- A small set of shared utilities used by both the applet and the scripted CLI flow: colored status lines, a generic spinner helper, and the shared lipgloss palette.
Index¶
- func RunApplet(data *AppletData, initial ...AppletInitial) error
- func RunWithSpinner(message string, task func() error) error
- func RunWithSpinnerResult[T any](message string, task func() (T, error)) (T, error)
- func Status(icon, msg string)
- func StatusErr(icon, msg string)
- type AppletCreateSeed
- type AppletData
- func NewAppletData(cfg *config.Config, cfgPath string) *AppletData
- func (d *AppletData) Codespaces() []codespace.Codespace
- func (d *AppletData) Config() *config.Config
- func (d *AppletData) ConfigPath() string
- func (d *AppletData) DeleteWorkspace(providerName, name string) error
- func (d *AppletData) EnsurePortsCache(csName string, onReady func()) PortCacheEntry
- func (d *AppletData) HealthCatalog() []doctor.Check
- func (d *AppletData) ListErr() error
- func (d *AppletData) ManagerForProvider(providerName string) (provider.Manager, error)
- func (d *AppletData) PersistConfig() error
- func (d *AppletData) Poll() PollResult
- func (d *AppletData) PortCache(name string) PortCacheEntry
- func (d *AppletData) PortForwards() *daemon.PortForwardManager
- func (d *AppletData) RefreshPorts(csName string) PortCacheEntry
- func (d *AppletData) ResolveWorkspace(providerName, name string) (*provider.Workspace, error)
- func (d *AppletData) StatusFor(name string) ProviderStatus
- func (d *AppletData) Workspaces() []provider.Workspace
- type AppletInitial
- type AppletModel
- func NewAppletModel(data *AppletData, initial ...AppletInitial) AppletModel
- func (m AppletModel) Init() tea.Cmd
- func (m AppletModel) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (m AppletModel) View() string
- type PollResult
- type PortCacheEntry
- type ProviderStatus
- type SpinnerModel
- func NewSpinnerModel(message string, task func() error) SpinnerModel
- func (m SpinnerModel) Init() tea.Cmd
- func (m SpinnerModel) Result() SpinnerResult
- func (m SpinnerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (m SpinnerModel) View() string
- type SpinnerResult
func RunApplet¶
RunApplet starts the persistent TUI applet using the given data layer. Pass an optional AppletInitial to pre-seed the view (filter, create pre-fill). Blocks until the user quits.
func RunWithSpinner¶
RunWithSpinner runs a task with a spinner, exiting the process with status 0 if the user interrupts with ctrl+c.
func RunWithSpinnerResult¶
RunWithSpinnerResult runs a task that returns a value, with a spinner.
func Status¶
Status prints a colored status line to stderr. Used by the CLI launch path to surface a one-line "ok / waiting / done" without owning a full Bubbletea program.
func StatusErr¶
StatusErr prints a colored error status line to stderr.
type AppletCreateSeed¶
AppletCreateSeed seeds the Create view with a chosen provider and an initial repository (GitHub) or workspace name (Coder).
type AppletData¶
AppletData owns the TUI applet's mutable state — workspace lists, provider health, port snapshots, and the long-lived port-forward supervisor. It's the TUI-side equivalent of daemon.Daemon, minus the Fyne pieces (windows, tray, hotkey listener) which a terminal doesn't need.
All exported methods are safe for concurrent use; the TUI's tea.Cmd callbacks read state from background goroutines while the foreground model is rendering.
func NewAppletData¶
NewAppletData wires the long-lived TUI state. Pass the parsed config and the absolute path it was loaded from so per-workspace SSH toggles can be persisted.
func (*AppletData) Codespaces¶
Codespaces returns a defensive copy of the last-polled codespace list.
func (*AppletData) Config¶
Config returns the live config pointer. Callers may mutate it (e.g. to toggle a per-workspace SSH option) and then call PersistConfig.
func (*AppletData) ConfigPath¶
ConfigPath returns the config file path used by PersistConfig.
func (*AppletData) DeleteWorkspace¶
DeleteWorkspace deletes a workspace through the right provider manager.
func (*AppletData) EnsurePortsCache¶
EnsurePortsCache returns the cached ports entry for a codespace, kicking off ONE async refresh when there is no cached entry yet. An entry that is already Loading is returned as-is — every repaint used to stack another `gh codespace ports` subprocess onto the in-flight one. The Loading placeholder is written under the lock before the goroutine starts so concurrent callers deduplicate too.
func (*AppletData) HealthCatalog¶
HealthCatalog builds the doctor catalog the settings Health section renders. Like the GUI, it includes every provider's auth check wired to that provider's own cached error, so a Coder login problem and a GitHub scope problem surface independently rather than only the effective provider's.
func (*AppletData) ListErr¶
ListErr returns the most recent provider list error, or nil.
func (*AppletData) ManagerForProvider¶
ManagerForProvider returns a provider.Manager for the named provider.
func (*AppletData) PersistConfig¶
PersistConfig writes the in-memory config back to disk. Returns nil if no path was configured (which can happen in tests).
func (*AppletData) Poll¶
Poll fetches the workspace list from every configured provider, refreshes per-provider status, and returns a single combined slice. Safe to call from a goroutine; concurrent calls collapse to one in-flight at a time.
func (*AppletData) PortCache¶
PortCache returns a snapshot of the ports section for the named codespace. Loading is true while a refresh is in flight.
func (*AppletData) PortForwards¶
PortForwards returns the shared supervisor used to start/stop forwards.
func (*AppletData) RefreshPorts¶
RefreshPorts fetches the ports section for a codespace and stores the result in the cache. Marks Loading=true for the duration so the detail view can render a spinner placeholder.
func (*AppletData) ResolveWorkspace¶
ResolveWorkspace finds a workspace by name through the right provider.
func (*AppletData) StatusFor¶
StatusFor returns a snapshot of the named provider's local-setup health.
func (*AppletData) Workspaces¶
Workspaces returns a defensive copy of the last-polled combined workspace list (GitHub codespaces + Coder workspaces, both translated to the unified provider.Workspace shape).
type AppletInitial¶
AppletInitial lets callers (notably the root `cosmonaut \<target>` flow) seed the applet's initial state — pre-filter the list to a repo, or jump straight to the Create view with a repo filled in. Zero value means "open the list view, no filter."
type AppletInitial struct {
// Filter pre-populates the list view's filter-as-you-type buffer.
// Useful when the user typed `cosmonaut <target>` and multiple
// workspaces matched — we open the applet narrowed to those.
Filter string
// Create, if non-nil, opens directly on the Create view with these
// fields pre-filled. Useful when `cosmonaut <target>` finds no
// existing workspace and the user wanted one created.
Create *AppletCreateSeed
}
type AppletModel¶
AppletModel is the top-level Bubbletea model. It owns the data layer and the currently-mounted sub-view, and routes Update / View calls to it.
func NewAppletModel¶
NewAppletModel constructs the top-level model. Pass the shared data layer; the model will trigger an initial poll on Init.
func (AppletModel) Init¶
func (AppletModel) Update¶
func (AppletModel) View¶
type PollResult¶
PollResult is sent back by Poll as a tea.Msg so the foreground model can re-render when fresh data lands. Workspaces is always set; ListErr is non-nil when the provider call failed end-to-end.
type PortCacheEntry¶
PortCacheEntry mirrors the daemon's port cache shape: a per-codespace snapshot used to render the ports section without re-fetching on every repaint.
type ProviderStatus¶
ProviderStatus mirrors daemon.ProviderStatus inside the TUI package so the list/detail/settings views don't have to import daemon directly.
type SpinnerModel¶
SpinnerModel runs a single background task with a spinner. Used by the CLI launch path for "Listing workspaces", "Preparing SSH config", etc.
func NewSpinnerModel¶
NewSpinnerModel creates a spinner that runs the given task in the background.
func (SpinnerModel) Init¶
Init kicks off both the spinner ticker and the background task.
func (SpinnerModel) Result¶
Result returns the spinner result.
func (SpinnerModel) Update¶
Update advances the spinner and exits when the background task signals done.
func (SpinnerModel) View¶
View renders the spinner + message line.
type SpinnerResult¶
SpinnerResult holds the outcome of a spinner task.
Generated by gomarkdoc