Documentation
¶
Overview ¶
Package ui contains the bubbletea TUI shell for Hygge.
Layering ¶
internal/ui may import: internal/agent, internal/bus, internal/cost, internal/session, internal/ui/theme, and stdlib. It must NOT import anything in cmd/. Task 13's main.go wraps the App in a tea.Program.
The App is a Model, not a Program ¶
New(opts) returns an *App that implements tea.Model (Init/Update/View). The CLI is responsible for constructing a *tea.Program around it. This keeps internal/ui drivable from tests without touching a TTY.
Bus bridge ¶
The App owns a single goroutine that fans every event we care about from the typed bus subscriptions into one `chan any`. Init returns a tea.Cmd that reads one event off that channel and wraps it in a [busDelivery] Msg; Update re-issues the same Cmd on every delivery, creating an infinite read-loop entirely inside the bubbletea Cmd machinery. No program-side Send is needed.
Close cancels the bridge context so the goroutine exits and tests can avoid leaks.
Index ¶
- func GenerateSystemPrompt(ctx context.Context, prv provider.Provider, modelName, idea string) (string, error)
- type App
- func (a *App) ActiveMode() *config.ModeConfig
- func (a *App) ActiveModeName() string
- func (a *App) Close() error
- func (a *App) Draw(scr uv.Screen, area uv.Rectangle) *tea.Cursor
- func (a *App) Handle(ev any) tea.Cmd
- func (a *App) Init() tea.Cmd
- func (a *App) SetProgram(p *tea.Program)
- func (a *App) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (a *App) View() tea.View
- type AppOptions
- type MentionSubagent
- type OnboardingResult
- type SidebarMCPStatus
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GenerateSystemPrompt ¶ added in v0.7.0
func GenerateSystemPrompt(ctx context.Context, prv provider.Provider, modelName, idea string) (string, error)
GenerateSystemPrompt uses the given provider to generate a system prompt for a mode/subagent described by idea. Returns the generated text or an error. This is a standalone helper used by run.go's GeneratePrompt callback.
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is the root bubbletea model.
func New ¶
func New(opts AppOptions) (*App, error)
New constructs the App. Validates required fields and starts the bus bridge goroutine.
func (*App) ActiveMode ¶
func (a *App) ActiveMode() *config.ModeConfig
ActiveMode returns the currently active mode config. Always returns non-nil because Modes is guaranteed to have at least one entry after config loading.
func (*App) ActiveModeName ¶
ActiveModeName returns the display name of the current mode.
func (*App) Close ¶
Close releases the bridge goroutine and any in-flight Send. Idempotent. Tests call this in t.Cleanup.
func (*App) Draw ¶
Draw renders the entire UI to a screen buffer. The left column (chat, chrome, editor, footer) is composed as a single content flow, then the sidebar and overlays are drawn into their own regions.
func (*App) Handle ¶
Handle delivers a single bus event synchronously, exactly as if it had arrived via the listener. Used by tests to drive the App without goroutines. Returns the same tea.Cmd Update would.
func (*App) Init ¶
Init is the bubbletea Model entry point. Starts the input focus, the spinner tick, and the bus listener.
func (*App) SetProgram ¶
SetProgram stores the tea.Program so that goroutines started by startSend can inject messages back into the bubbletea event loop via program.Send. Must be called before the first Update that triggers a send. The CLI calls it immediately after tea.NewProgram. Tests leave it unset; sendOutOfBand is a no-op when program is nil, so tests drive sendCompleted manually via app.Update(sendCompleted{...}).
type AppOptions ¶
type AppOptions struct {
Bus *bus.Bus
Agent *agent.Agent
Store session.Store
Catalog *cost.Catalog
Theme *theme.Theme
// StyleTheme selects the built-in color theme for the new styles system.
StyleTheme string
// Modes is the ordered list of agent modes the user can cycle through
// with Tab. Each mode specifies a provider, model, and optional
// reasoning/prompt. Guaranteed non-empty after config loading.
Modes []config.ModeConfig
// AuthConfiguredProviders lists providers with global auth configured
// (env var or auth store), independent of the active profile.
AuthConfiguredProviders []string
SessionID string // existing session to resume, or "" to create on first input
ProjectDir string
ModelProvider string // "anthropic" etc, for status bar display
ModelName string
ProfileName string
Reasoning provider.Reasoning
Commands *command.Registry // slash-command registry; nil disables slash routing
Subagents []MentionSubagent // sub-agent types selectable from @ mentions
Now func() time.Time
// ContextWindow is the model's maximum context size in tokens. Used by
// the compaction modal to display usage info. 0 means unknown.
ContextWindow int64
// Version is the application version string shown in persistent chrome (e.g. "v0.4").
// Empty string hides the version.
Version string
// NerdFonts controls whether nerd-font glyphs are used in persistent chrome.
// When true, the git-branch glyph (U+EAFC) is used; otherwise ":branch".
// Default false; callers should set this from config.UI.NerdFonts.
NerdFonts bool
// HomeDir is the user's home directory, used for tilde-collapsing the
// project path in persistent chrome. Empty → no collapse.
HomeDir string
// OnSessionCreated, if non-nil, is invoked after the App lazily
// creates a new session on first Send. The CLI uses this to record
// the new id in state (RecentSessions). Best-effort; errors are
// swallowed internally.
OnSessionCreated func(id string)
// MCPStatuses is the list of MCP server statuses populated at bootstrap.
// Displayed in the sidebar. The UI-side type is SidebarMCPStatus (defined
// in components/sidebar.go) so the UI package has no dependency on cmd/.
MCPStatuses []components.SidebarMCPStatus
// OpenSessionsModalOnStart, when true, causes the sessions picker to
// open immediately after the first render. Used by `hygge resume`
// (multiple sessions in cwd) and resume_default="ask". When the
// picker is opened this way and the user presses Esc without selecting
// a session — and no foreground session is bound — the App exits.
OpenSessionsModalOnStart bool
// Config is the resolved application configuration. When non-nil,
// the notifications subsystem reads Config.Notifications to decide
// whether and when to send notifications. A nil Config disables
// notifications (equivalent to Config.Notifications.Enabled == false).
Config *config.Config
// SwitchModel applies a provider/model selection to the running backend.
// modeName is non-empty when the switch came from a mode change; it is empty
// for direct /model selections. When nil, /model remains a session-only UI
// selection.
SwitchModel func(ctx context.Context, providerName, modelName, modeName string) error
// SaveModel persists a successful provider/model runtime switch. Save
// failures are surfaced to the UI without rolling back the runtime switch.
SaveModel func(ctx context.Context, providerName, modelName string) error
SaveAPIKey func(ctx context.Context, providerName, apiKey string) error
// RememberMemory persists project/global memory. Session memory uses Store.
RememberMemory func(ctx context.Context, scope session.MemoryScope, content string) (*session.Memory, error)
// ForgetMemory deletes project/global memory. Session memory uses Store.
ForgetMemory func(ctx context.Context, scope session.MemoryScope, memoryID string) (*session.Memory, error)
// ListMemories loads file-backed global/project memories. Session memory uses Store.
ListMemories func(ctx context.Context) ([]*session.Memory, error)
// ProjectMemoryGitignoreWarning returns a warning before the first project memory
// write when .hygge/ may become untracked.
ProjectMemoryGitignoreWarning func(ctx context.Context) (string, error)
ThemeNames []string
LoadTheme func(ctx context.Context, name string) (*theme.Theme, error)
SaveTheme func(ctx context.Context, name string) error
// EditPrompt opens the current prompt in an external editor and returns the
// edited prompt. Tests may inject this seam; production falls back to
// $VISUAL, then $EDITOR, then vi.
EditPrompt func(ctx context.Context, initial string) (string, error)
// NeedsOnboarding opens the first-run onboarding wizard before chat.
NeedsOnboarding bool
// KnownProviders lists provider IDs selectable in onboarding.
KnownProviders []string
// SaveOnboardingResult persists the completed onboarding configuration.
SaveOnboardingResult func(ctx context.Context, result OnboardingResult) error
// GeneratePrompt generates a system prompt during onboarding. It should return
// an error without blocking manual editing when generation fails.
GeneratePrompt func(ctx context.Context, providerName, modelName, apiKey, idea string) (string, error)
// Yolo bypasses configurable permission prompts/default denies while keeping
// the hard-coded secrets denylist active.
Yolo bool
SetYolo func(ctx context.Context, enabled bool) error
}
AppOptions configures the App.
type MentionSubagent ¶
MentionSubagent is the UI-facing description of a selectable sub-agent type. The CLI maps internal/subagent.Type values into this shape so internal/ui can render @ mention completions without depending on the subagent package.
type OnboardingResult ¶ added in v0.7.0
type OnboardingResult struct {
// ProviderName is the provider selected for the first mode.
ProviderName string
// ProviderAPIKey is the raw API key for ProviderName.
ProviderAPIKey string
// ProviderAPIKeys contains every provider API key configured during onboarding.
ProviderAPIKeys map[string]string
// Mode is the first mode the user created.
Mode config.ModeConfig
// Subagents lists the subagent definitions the user created.
Subagents []components.OnboardingSubagentDraft
}
OnboardingResult is the output of the onboarding wizard passed to AppOptions.SaveOnboardingResult.
type SidebarMCPStatus ¶
type SidebarMCPStatus = components.SidebarMCPStatus
SidebarMCPStatus is a re-export of components.SidebarMCPStatus so that cmd/hygge/cli/run.go can reference the type without importing the internal/ui/components package directly. See AppOptions.MCPStatuses.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package components contains the bubbletea sub-views that compose the App.
|
Package components contains the bubbletea sub-views that compose the App. |
|
anim
Package anim provides a compact colored-runes animation component for use in terminal UIs built with bubbletea v2.
|
Package anim provides a compact colored-runes animation component for use in terminal UIs built with bubbletea v2. |
|
bubble
Package bubble provides the Bubble rendering primitive for the chat-bubble UI redesign (Phase 1).
|
Package bubble provides the Bubble rendering primitive for the chat-bubble UI redesign (Phase 1). |
|
Package styles defines the comprehensive style system for Hygge's terminal UI.
|
Package styles defines the comprehensive style system for Hygge's terminal UI. |
|
Package theme provides the theme registry and style-atom system for Hygge's terminal UI.
|
Package theme provides the theme registry and style-atom system for Hygge's terminal UI. |