Documentation
¶
Overview ¶
Package app is declared in page.go; this file adds the App root model.
Package app defines the core types for the PromptArena TUI hub shell: the Page interface that every screen implements, AppContext that carries shared runtime dependencies, and the navigation messages used to push/pop pages or signal quit and config-change events.
Index ¶
- func DefaultMenu(ctx *AppContext) []menuItem
- func DiscoverConfig(dir string) (path string, found bool)
- func ResultsDirFromConfig(configPath string) string
- func Run(ctx *AppContext, root Page) error
- type Activatable
- type App
- type AppContext
- type ChatPage
- type Closeable
- type ConfigChangedMsg
- type ConfigSwitchPage
- type ConversationViewPage
- type Home
- type InspectPage
- type Page
- type PopPageMsg
- type PushPageMsg
- type QuitMsg
- type ResultsPage
- type RunPage
- func (p *RunPage) Activate(send func(tea.Msg)) tea.Cmd
- func (p *RunPage) Cancel()
- func (p *RunPage) Init() tea.Cmd
- func (p *RunPage) Model() *tui.Model
- func (p *RunPage) Results() (runIDs []string, finished bool, err error)
- func (p *RunPage) SetSize(w, h int)
- func (p *RunPage) Title() string
- func (p *RunPage) Update(msg tea.Msg) (Page, tea.Cmd)
- func (p *RunPage) View() string
- type Splash
- type ViewPage
- type VoiceOptions
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DefaultMenu ¶
func DefaultMenu(ctx *AppContext) []menuItem
DefaultMenu returns the canonical menu items for the Home page.
View is always enabled (it only needs a results directory). Run, Chat, and Inspect require a loaded config.
func DiscoverConfig ¶
DiscoverConfig resolves an arena config path from dir.
If dir is itself a regular file it is returned directly. If dir is a directory, DiscoverConfig looks for config.arena.yaml inside it. Returns (path, true) on success or ("", false) when no config can be found.
func ResultsDirFromConfig ¶
ResultsDirFromConfig returns the conventional results directory (out/) next to the given config file. Callers that build an AppContext directly (e.g. chat/config-inspect subcommands) use this so the path matches what LoadConfig would have set.
func Run ¶
func Run(ctx *AppContext, root Page) error
Run launches the PromptArena TUI hub with root as the bottom page on the navigation stack. The splash screen is shown first — it is pushed on top of root so that dismissing it (via any key or the auto-dismiss timer) reveals root. App.Init() calls the top page's Init (once only), so the splash timer fires automatically under the bubbletea runtime.
The stack is seeded as [root, splash] before tea.NewProgram is called, which means:
- a.Init() → splash.Init() (timer starts; root is NOT yet inited)
- splash dismiss → PopPageMsg → root becomes top → root.Init() fires once (via initAndActivate in pop()) together with root.Activate() if applicable
The once-only Init guarantee ensures deep-link pages like ChatPage load their agents/setup state when revealed by splash dismiss, not before. Esc/q at root (the only page remaining after splash dismiss) will quit.
Types ¶
type Activatable ¶
Activatable is implemented by pages that need to push async messages into the running bubbletea program. The App calls Activate(send) when the page becomes the active/top page: at root startup (in App.Init) and on push. send is *tea.Program.Send — a thread-safe delivery channel. The returned tea.Cmd is an optional startup command; it is batched with the page's Init cmd by the App.
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is the root bubbletea model for the PromptArena TUI hub shell. It owns the page navigation stack and routes messages globally.
func New ¶
func New(ctx *AppContext, root Page) *App
New creates a new App with root as the initial (bottom) page on the stack. root must not be nil.
func (*App) Init ¶
Init implements tea.Model. It runs the top page's Init command (once only) and batches it with an optional Activate cmd if the page implements Activatable.
func (*App) SetSend ¶
SetSend stores the program's Send func so that Activatable pages can push messages back into the bubbletea event loop from goroutines. Call this after tea.NewProgram and before p.Run().
type AppContext ¶
type AppContext struct {
Config *config.Config
ConfigPath string
ResultsDir string
StateStore statestore.Store
Engine *engine.Engine
Version string
Voice *VoiceOptions // nil => text chat
}
AppContext carries the shared runtime dependencies injected into every Page by the hub shell. Fields are set once at startup and then treated as read-only by pages.
func (*AppContext) EnsureEngine ¶
func (c *AppContext) EnsureEngine() (*engine.Engine, error)
EnsureEngine returns the cached engine from ctx, building it from ctx.Config if it has not been built yet. It also sets ctx.StateStore from the engine. Returns an error if no config has been loaded.
func (*AppContext) HasConfig ¶
func (c *AppContext) HasConfig() bool
HasConfig reports whether a config has been loaded into this context.
func (*AppContext) LoadConfig ¶
func (c *AppContext) LoadConfig(path string) error
LoadConfig loads the arena configuration from path, sets Config and ConfigPath on the context, and derives ResultsDir as the out/ directory next to the config file.
type ChatPage ¶
type ChatPage struct {
// contains filtered or unexported fields
}
ChatPage is a hub Page that drives the interactive chat console. It owns the setup flow (agent / provider / variable selection) and the live chat panel driven from the state store after each turn.
Implements Page and Activatable.
func NewChatPage ¶
func NewChatPage(ctx *AppContext) *ChatPage
NewChatPage constructs a ChatPage bound to the given AppContext. Activate must be called before Init to wire the engine.
func (*ChatPage) Activate ¶
Activate implements Activatable. It is called by App before Init. It calls EnsureEngine so Init can proceed. The send handle is stored so startVoice can push messages into the bubbletea loop from goroutines.
func (*ChatPage) Close ¶
func (p *ChatPage) Close()
Close implements Closeable. It cancels any running voice driver so the mic and pipeline shut down cleanly when the user quits.
func (*ChatPage) Init ¶
Init implements Page. It resolves the first setup step, auto-selecting when there is only one agent or provider so simple configs drop straight into chat.
type Closeable ¶
type Closeable interface {
Close()
}
Closeable is an optional interface a Page may implement to run cleanup logic when the App exits (e.g. canceling a background voice driver). App calls Close on every page in the stack when it processes a tea.Quit or QuitMsg.
type ConfigChangedMsg ¶
type ConfigChangedMsg struct{ Path string }
ConfigChangedMsg is emitted when the user loads or changes the arena config file. Path is the absolute path to the newly loaded file.
type ConfigSwitchPage ¶
type ConfigSwitchPage struct {
// contains filtered or unexported fields
}
ConfigSwitchPage wraps the file browser to let the user pick an arena config at runtime. On a successful selection it calls ctx.LoadConfig then emits both ConfigChangedMsg and PopPageMsg. On error it stays open and surfaces the error in its View.
func NewConfigSwitchPage ¶
func NewConfigSwitchPage(ctx *AppContext, startDir string) *ConfigSwitchPage
NewConfigSwitchPage creates a ConfigSwitchPage rooted at startDir. startDir is the initial directory shown in the file browser; a sensible default (dir of the current config, or ".") is chosen by callers.
func (*ConfigSwitchPage) Init ¶
func (p *ConfigSwitchPage) Init() tea.Cmd
Init implements Page. Delegates to the underlying file browser.
func (*ConfigSwitchPage) SetSize ¶
func (p *ConfigSwitchPage) SetSize(w, h int)
SetSize implements Page. Stores dimensions for View; does NOT call SetDimensions on the browser here because Render() is called from View() where we apply dimensions immediately before rendering.
func (*ConfigSwitchPage) Update ¶
Update implements Page. It intercepts FileSelectedMsg from the browser and drives the load-config flow; all other messages are forwarded to the browser.
Filtering note: FileBrowserPage uses AllowedTypes (extension list) which does not support glob patterns like "*.arena.yaml". The browser is therefore left unrestricted; invalid selections (non-YAML, non-arena files) are rejected via the LoadConfig error path and surfaced in the view.
func (*ConfigSwitchPage) View ¶
func (p *ConfigSwitchPage) View() string
View implements Page. Shows the file browser, or an error banner when the last selection failed.
type ConversationViewPage ¶
type ConversationViewPage struct {
// contains filtered or unexported fields
}
ConversationViewPage wraps pages.ConversationPage for use inside the hub shell navigation stack.
func NewConversationViewPage ¶
func NewConversationViewPage(runID, scenarioID, providerID string, result *statestore.RunResult) *ConversationViewPage
NewConversationViewPage creates a ConversationViewPage pre-loaded with the given run data.
func (*ConversationViewPage) Init ¶
func (p *ConversationViewPage) Init() tea.Cmd
Init implements Page.
func (*ConversationViewPage) SetSize ¶
func (p *ConversationViewPage) SetSize(w, h int)
SetSize implements Page.
func (*ConversationViewPage) Title ¶
func (p *ConversationViewPage) Title() string
Title implements Page.
func (*ConversationViewPage) Update ¶
Update implements Page. Forwards messages to the underlying conversation panel.
func (*ConversationViewPage) View ¶
func (p *ConversationViewPage) View() string
View implements Page.
type Home ¶
type Home struct {
// contains filtered or unexported fields
}
Home is the top-level navigation page for the PromptArena TUI hub shell. It is generic over its menu items so that the concrete Run/View/Chat/Inspect entries can be injected by the top-level wiring (Task 8) without baking them in here.
func NewHome ¶
func NewHome(ctx *AppContext, items []menuItem) *Home
NewHome creates a Home page backed by ctx and populated with items. Items whose needsConfig field is true are greyed and non-selectable when ctx.HasConfig() returns false.
type InspectPage ¶
type InspectPage struct {
// contains filtered or unexported fields
}
InspectPage is a scrollable hub page that displays the configuration inspector output (the same content as `promptarena config-inspect`).
func NewInspectPage ¶
func NewInspectPage(ctx *AppContext) *InspectPage
NewInspectPage creates an InspectPage with default render options. If ctx is nil or has no config loaded, a placeholder message is shown instead. This is the entry point used by the Home menu.
func NewInspectPageWithOptions ¶
func NewInspectPageWithOptions(ctx *AppContext, opts inspect.RenderOptions) *InspectPage
NewInspectPageWithOptions creates an InspectPage with the given render options, allowing callers to thread --verbose/--section/--stats/--short flags through from the CLI. If ctx is nil or has no config loaded, a placeholder is shown.
func (*InspectPage) SetSize ¶
func (p *InspectPage) SetSize(w, h int)
SetSize implements Page. Initializes (or re-initializes) the viewport.
type Page ¶
type Page interface {
Init() tea.Cmd
Update(tea.Msg) (Page, tea.Cmd)
View() string
Title() string
SetSize(w, h int)
}
Page is the interface that every screen in the TUI hub must implement. It mirrors the bubbletea Model interface but returns (Page, tea.Cmd) from Update so that the shell can swap the active page in response to navigation messages.
type PopPageMsg ¶
type PopPageMsg struct{}
PopPageMsg instructs the hub shell to pop the current page, returning to the previous one.
type PushPageMsg ¶
type PushPageMsg struct{ Page Page }
PushPageMsg instructs the hub shell to push a new page onto the navigation stack, making it the active page.
type ResultsPage ¶
type ResultsPage struct {
// contains filtered or unexported fields
}
ResultsPage wraps MainPage to display the results loaded from a summary (index.json). The user can navigate the runs table and press Enter to dive into a ConversationViewPage.
func NewResultsPage ¶
func NewResultsPage(summary map[string]interface{}, resultsDir string) *ResultsPage
NewResultsPage creates a ResultsPage for the given summary and directory.
func (*ResultsPage) Init ¶
func (p *ResultsPage) Init() tea.Cmd
Init implements Page. Triggers async loading of all run results listed in the summary.
type RunPage ¶
type RunPage struct {
// contains filtered or unexported fields
}
RunPage drives the live run view inside the hub shell. It wraps the tui.Model (the 3-pane runs/logs/result view) and, on Activate, wires an event bus + adapter to stream runtime events into the model and kicks off engine.ExecuteRuns in a background goroutine. Drill-down into a run's conversation is handled at the App-stack level: when the model reports a selected run, RunPage pushes a ConversationViewPage loaded from the state store.
Implements Page and Activatable.
func NewRunPage ¶
func NewRunPage( ctx *AppContext, eng *engine.Engine, plan *engine.RunPlan, concurrency int, configFile string, totalRuns int, ) *RunPage
NewRunPage builds a RunPage for the given engine and run plan. The run command performs setupEngine / plan generation and hands the results in; RunParameters lives in package main and cannot be imported here, so callers pass the already-built engine, plan, concurrency, configFile and totalRuns.
func NewRunPageFromContext ¶
func NewRunPageFromContext(ctx *AppContext) (*RunPage, error)
NewRunPageFromContext is a convenience constructor for the Home menu factory. It calls EnsureEngine, generates a full (unfiltered) run plan, and returns a RunPage ready to be pushed onto the navigation stack. The default concurrency is 1 so the menu can always succeed without extra flags.
func (*RunPage) Activate ¶
Activate implements Activatable. It wires the event bus + adapter to deliver runtime events via send and starts ExecuteRuns in the background. The run results persist to the engine's state store as today. Returns the model's Init command.
func (*RunPage) Cancel ¶
func (p *RunPage) Cancel()
Cancel stops the background run. Safe to call after the hub exits so an early quit ('q' / Ctrl+C) does not leak the ExecuteRuns goroutine.
func (*RunPage) Results ¶
Results returns the run IDs produced by ExecuteRuns, whether the run finished, and any execution error. Safe for concurrent use; intended to be read by the run command after the hub exits.
func (*RunPage) SetSize ¶
SetSize implements Page. Forwards the terminal size to the model as a WindowSizeMsg (the model tracks its own width/height).
type Splash ¶
type Splash struct {
// contains filtered or unexported fields
}
Splash is the transient splash-screen Page shown at launch. It displays the locked PromptKit logo, a wordmark with the version, and a tagline. It dismisses on any key press or after splashDuration.
func NewSplash ¶
func NewSplash(ctx *AppContext) *Splash
NewSplash creates a Splash page backed by the given AppContext. The version string from ctx is rendered on the screen; pass ctx.Version = "vTEST" (or similar fixed string) in golden tests to keep output byte-stable.
type ViewPage ¶
type ViewPage struct {
// contains filtered or unexported fields
}
ViewPage wraps a file browser to let the user navigate past Arena result directories. Selecting a file triggers an async load; the result msg is then used to push either a ResultsPage (index.json) or ConversationViewPage.
func NewViewPage ¶
NewViewPage creates a ViewPage rooted at resultsDir.
type VoiceOptions ¶
type VoiceOptions struct {
STTProviderID string // --voice-stt ("" = ASM/native realtime mode)
OutputVoice string // --voice-output-voice
EchoGuard bool // --echo-guard
BargeIn bool // --barge-in (interrupt the agent mid-reply; opt-in)
}
VoiceOptions carries the voice-mode parameters parsed from CLI flags. A nil *VoiceOptions on AppContext means text-chat mode.