Documentation
¶
Overview ¶
Package app holds the Bubble Tea Model, Update, View, and message types for the paddock-tui interactive UI.
Index ¶
Constants ¶
const NewSessionSentinel = "__paddock_tui_new_session__"
NewSessionSentinel is a synthetic entry placed at the end of the visible sidebar list, representing the "[+ new session]" row. It's a valid value of m.Focused — pressing Enter on it opens the new-session modal. The string is deliberately unrepresentable as a Workspace name (Workspace names are DNS labels: lowercase alphanumerics and hyphens) so it can never collide with a real session.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type EndSessionModalState ¶
type InteractiveBinding ¶
InteractiveBinding holds the TUI's view of an Interactive HarnessRun the focused session is bound to. CurrentTurnSeq mirrors HarnessRun.status.interactive.currentTurnSeq — non-nil means a turn is in flight; nil means the run is between prompts.
type Model ¶
type Model struct {
// Cluster wiring.
Client client.Client
Namespace string
// BrokerClient is the authenticated HTTP+WebSocket client for the
// paddock-broker. Nil until Phase 5 wire-up populates it from the
// binary entry point. Unit tests that do not exercise the broker
// call leaf leave it nil.
BrokerClient *paddockbroker.Client
// Session list, keyed by Name. SessionOrder gives display order.
Sessions map[string]*SessionState
SessionOrder []string
Focused string // session name; "" when no session selected.
// UI state.
FocusArea FocusArea
Modal ModalKind
PromptInput string
Filter string
// ErrBanner surfaces transient error messages (red / high-attention).
ErrBanner string
// Banner surfaces informational context messages (e.g. run ended).
// Distinct from ErrBanner so render code can colour them differently.
Banner string
// PendingPrompt holds a single submitted prompt that's waiting for
// the broker to stop returning 409 (an in-flight turn on the bound
// interactive run). Submitting another prompt while non-empty
// replaces this one. The status footer surfaces a hint.
PendingPrompt string
// Palette tracks the command palette overlay's open/closed state and
// in-progress input. See palette.go.
Palette PaletteState
// Modal-specific state, set when Modal != ModalNone.
ModalNew *NewSessionModalState
ModalEnd *EndSessionModalState
ModalHelp bool
ModalQueue bool
// MainScrollFromBottom is the number of lines the main pane has
// been scrolled UP from the bottom. 0 means stick to bottom (the
// most recent run is fully visible). PgUp/PgDown adjust this in
// the reducer; the View slices the rendered content accordingly.
MainScrollFromBottom int
// RunCursor indexes into the focused session's Runs slice for
// keyboard navigation. Only meaningful when FocusArea == FocusMainPane.
RunCursor int
// contains filtered or unexported fields
}
Model is the Bubble Tea model for paddock-tui. Everything that renders or affects rendering lives here. Async work is driven by tea.Cmd values returned from Update — see commands.go.
func (Model) Init ¶
Init kicks off the initial session-list load and opens the session watch. The session watch is opened once for the lifetime of the Model — Update re-issues nextSessionEventCmd to read further events off the same channel without spawning new goroutines.
type NewSessionModalState ¶
type NewSessionModalState struct {
NameInput string
TemplatePicks []string // populated from session.ListTemplates
TemplateIdx int
StorageInput string
SeedRepoInput string
Field int // 0=name, 1=template, 2=storage, 3=seed
}
Modal-state placeholders — implementations land in Task 17.
type PaletteCmd ¶
type PaletteCmd int
PaletteCmd identifies a recognised palette command. PaletteEmpty covers the "user opened the palette but hasn't typed anything yet" case; PaletteUnknown carries the typed token back to the caller for error reporting.
const ( PaletteEmpty PaletteCmd = iota PaletteCancel PaletteEnd PaletteInteractive PaletteTemplate PaletteReattach PaletteStatus PaletteEdit PaletteHelp PaletteUnknown )
func ParsePalette ¶
func ParsePalette(input string) (PaletteCmd, string)
ParsePalette classifies a palette command line. The returned arg is any whitespace-separated tail (e.g. for `template claude-code`). Empty input returns PaletteEmpty so the dispatcher can treat Enter-on-empty as a no-op cleanly.
type PaletteState ¶
type PaletteState struct {
// contains filtered or unexported fields
}
PaletteState tracks the palette overlay's runtime state. Closed palettes carry no input; opening starts with an empty buffer.
func (PaletteState) Input ¶
func (p PaletteState) Input() string
func (PaletteState) Open ¶
func (p PaletteState) Open() bool
func (PaletteState) WithInput ¶
func (p PaletteState) WithInput(s string) PaletteState
WithInput sets the in-progress input string. Caller is responsible for keeping the palette open; closed palettes ignore input writes (a no-op so the field stays "" on close).
func (PaletteState) WithOpen ¶
func (p PaletteState) WithOpen(open bool) PaletteState
WithOpen toggles the palette open/closed. Closing clears any in-progress input so the next open lands on an empty prompt.
type Queue ¶
type Queue struct {
// contains filtered or unexported fields
}
Queue is a tiny FIFO of pending prompts for one session. Lives in TUI memory only — quitting the TUI loses queued prompts by design.
type RunSummary ¶
type RunSummary struct {
Name string
// CreationTime mirrors HarnessRun.metadata.creationTimestamp.
// Used to sort SessionState.Runs chronologically. StartTime alone
// is insufficient because it stays zero until the harness pod
// starts, so freshly-created runs would otherwise sort ahead of
// older in-progress ones.
CreationTime time.Time
Phase paddockv1alpha1.HarnessRunPhase
Prompt string
StartTime time.Time
CompletionTime time.Time
Template string
}
RunSummary is a TUI-shaped projection of a HarnessRun.
func (RunSummary) IsTerminal ¶
func (r RunSummary) IsTerminal() bool
IsTerminal reports whether the run has reached a terminal phase.
type SessionMode ¶
type SessionMode int
SessionMode is the high-level state of a TUI session.
const ( SessionBatch SessionMode = iota SessionArmed SessionBound )
type SessionState ¶
type SessionState struct {
Session pdksession.Session
// Runs is the list of HarnessRuns for this session, sorted by
// CreationTime ascending (oldest first, newest at the end). The
// main pane renders backwards from the end so the newest run is at
// the top.
Runs []RunSummary
// Events keyed by run name. Only populated for the focused session.
Events map[string][]paddockv1alpha1.PaddockEvent
// Queue of prompts pending while a run is in flight.
Queue Queue
// Armed is true when the user has run the `interactive` palette
// command but hasn't yet typed the kick-off prompt.
Armed bool
// Interactive holds the bound interactive run, when the session is
// in SessionBound. Nil otherwise.
Interactive *InteractiveBinding
}
SessionState bundles the runtime state for one session held in TUI memory.
func (*SessionState) Mode ¶
func (s *SessionState) Mode() SessionMode
Mode reports the session's current high-level state, derived from SessionState fields.