Documentation
¶
Overview ¶
Package tui provides the Bubbletea-based terminal user interface for fab.
Index ¶
- Constants
- Variables
- func Run() error
- func RunWithClient(client daemon.TUIClient, opts *TUIOptions) error
- type AgentList
- func (l *AgentList) Agents() []daemon.AgentStatus
- func (l *AgentList) IsFocused() bool
- func (l *AgentList) MoveDown()
- func (l *AgentList) MoveToBottom()
- func (l *AgentList) MoveToTop()
- func (l *AgentList) MoveUp()
- func (l *AgentList) Selected() *daemon.AgentStatus
- func (l *AgentList) SelectedIndex() int
- func (l *AgentList) SetAgents(agents []daemon.AgentStatus)
- func (l *AgentList) SetFocused(focused bool)
- func (l *AgentList) SetNeedsAttention(agentIDs map[string]bool)
- func (l *AgentList) SetSelected(index int)
- func (l *AgentList) SetSize(width, height int)
- func (l *AgentList) SetSpinnerFrame(frame int)
- func (l AgentList) View() string
- type ChatView
- func (v *ChatView) AgentID() string
- func (v *ChatView) AppendEntry(entry daemon.ChatEntryDTO)
- func (v *ChatView) ClearAgent()
- func (v *ChatView) ClearPlanProjectSelection()
- func (v *ChatView) ClearPlanPromptMode()
- func (v *ChatView) ClearSupervisorProjectSelection()
- func (v *ChatView) GetSelectedAnswer() (header string, label string, isOther bool)
- func (v *ChatView) HasPendingPermission() bool
- func (v *ChatView) HasPendingUserQuestion() bool
- func (v *ChatView) IsFocused() bool
- func (v *ChatView) PageDown()
- func (v *ChatView) PageUp()
- func (v *ChatView) PendingPermissionID() string
- func (v *ChatView) PendingUserQuestionID() string
- func (v *ChatView) Project() string
- func (v *ChatView) QuestionMoveDown()
- func (v *ChatView) QuestionMoveUp()
- func (v *ChatView) ScrollDown(n int)
- func (v *ChatView) ScrollToBottom()
- func (v *ChatView) ScrollToTop()
- func (v *ChatView) ScrollUp(n int)
- func (v *ChatView) SetAbortConfirming(confirming bool, agentID string)
- func (v *ChatView) SetAgent(agentID, project, backend, worktree string)
- func (v *ChatView) SetEntries(entries []daemon.ChatEntryDTO)
- func (v *ChatView) SetFocused(focused bool)
- func (v *ChatView) SetInputView(view string, height int, focused bool)
- func (v *ChatView) SetPendingPermission(req *daemon.PermissionRequest)
- func (v *ChatView) SetPendingUserQuestion(question *daemon.UserQuestion)
- func (v *ChatView) SetPlanProjectSelection(projects []string, selectedIndex int)
- func (v *ChatView) SetPlanProjectSelectionWithFilter(projects []string, selectedIndex int, filter string)
- func (v *ChatView) SetPlanPromptMode(project string)
- func (v *ChatView) SetSize(width, height int)
- func (v *ChatView) SetSupervisorProjectSelection(projects []string, selectedIndex int, running map[string]bool)
- func (v *ChatView) SetSupervisorProjectSelectionWithFilter(projects []string, selectedIndex int, running map[string]bool, filter string)
- func (v ChatView) View() string
- type EventStreamer
- type Focus
- type Header
- type HelpBar
- type InputLine
- func (i *InputLine) AddToHistory(input string)
- func (i *InputLine) Clear()
- func (i *InputLine) ContentHeight() int
- func (i *InputLine) Focus()
- func (i *InputLine) HistoryDown() bool
- func (i *InputLine) HistoryUp() bool
- func (i *InputLine) InsertNewline()
- func (i *InputLine) IsFocused() bool
- func (i *InputLine) ResetHistoryNavigation()
- func (i *InputLine) SetFocused(focused bool)
- func (i *InputLine) SetPlaceholder(text string)
- func (i *InputLine) SetSize(width, height int)
- func (i *InputLine) Update(msg tea.Msg) tea.Cmd
- func (i *InputLine) Value() string
- func (i InputLine) View() string
- type KeyBindings
- type Mode
- type ModeState
- func (s *ModeState) CancelAbort() error
- func (s *ModeState) CancelPlanProjectSelect() error
- func (s *ModeState) CancelPlanPromptMode() error
- func (s *ModeState) CancelSupervisorProjectSelect() error
- func (s *ModeState) ConfirmAbort() (string, error)
- func (s *ModeState) CycleFocus() (Focus, error)
- func (s *ModeState) EnterAbortConfirm(agentID string) error
- func (s *ModeState) EnterInputMode() error
- func (s *ModeState) EnterPlanProjectSelect(projects []string) error
- func (s *ModeState) EnterSupervisorProjectSelect(projects []string, running map[string]bool) error
- func (s *ModeState) EnterUserQuestionMode() error
- func (s *ModeState) ExitInputMode() error
- func (s *ModeState) ExitPlanPromptMode() (string, error)
- func (s *ModeState) ExitUserQuestionMode() error
- func (s *ModeState) IsAbortConfirming() bool
- func (s *ModeState) IsInputting() bool
- func (s *ModeState) IsNormal() bool
- func (s *ModeState) IsPlanProjectSelect() bool
- func (s *ModeState) IsPlanPrompt() bool
- func (s *ModeState) IsSupervisorProjectSelect() bool
- func (s *ModeState) IsUserQuestion() bool
- func (s *ModeState) NeedsApproval() bool
- func (s *ModeState) PlanProjectAppendFilter(ch rune)
- func (s *ModeState) PlanProjectBackspaceFilter()
- func (s *ModeState) PlanProjectFilterState() string
- func (s *ModeState) PlanProjectSelectDown()
- func (s *ModeState) PlanProjectSelectUp()
- func (s *ModeState) PlanProjectSetFilter(filter string)
- func (s *ModeState) SelectPlanProject() (string, error)
- func (s *ModeState) SelectSupervisorProject() (project string, wasRunning bool, err error)
- func (s *ModeState) SelectedPlanProject() (string, []string, int)
- func (s *ModeState) SelectedSupervisorProject() ([]string, int, map[string]bool)
- func (s *ModeState) SetFocus(focus Focus) error
- func (s *ModeState) SetPendingApprovals(hasPermission, hasAction, hasUserQuestion bool)
- func (s *ModeState) SupervisorProjectAppendFilter(ch rune)
- func (s *ModeState) SupervisorProjectBackspaceFilter()
- func (s *ModeState) SupervisorProjectFilterState() string
- func (s *ModeState) SupervisorProjectSelectDown()
- func (s *ModeState) SupervisorProjectSelectUp()
- func (s *ModeState) SupervisorProjectSetFilter(filter string)
- func (s *ModeState) Validate() error
- type Model
- type TUIOptions
Constants ¶
const DirectorAgentID = "director"
DirectorAgentID is the special agent ID for the director agent.
const ManagerAgentID = "manager"
ManagerAgentID is the special agent ID for the manager agent.
const PlannerAgentIDPrefix = "plan:"
PlannerAgentIDPrefix is the prefix for planner agents in the agent list.
Variables ¶
var ( ErrInvalidModeTransition = errors.New("invalid mode transition") ErrMissingAgentID = errors.New("abort requires an agent ID") ErrAlreadyInMode = errors.New("already in this mode") )
Validation errors for mode state transitions.
Functions ¶
func RunWithClient ¶
func RunWithClient(client daemon.TUIClient, opts *TUIOptions) error
RunWithClient starts the TUI with a pre-connected daemon client.
Types ¶
type AgentList ¶
type AgentList struct {
// contains filtered or unexported fields
}
AgentList displays a navigable list of agents with status indicators.
func (*AgentList) Agents ¶
func (l *AgentList) Agents() []daemon.AgentStatus
Agents returns the current agent list.
func (*AgentList) MoveToBottom ¶
func (l *AgentList) MoveToBottom()
MoveToBottom moves selection to the last item.
func (*AgentList) MoveToTop ¶
func (l *AgentList) MoveToTop()
MoveToTop moves selection to the first item.
func (*AgentList) Selected ¶
func (l *AgentList) Selected() *daemon.AgentStatus
Selected returns the currently selected agent, or nil if none.
func (*AgentList) SelectedIndex ¶
SelectedIndex returns the current selection index.
func (*AgentList) SetAgents ¶
func (l *AgentList) SetAgents(agents []daemon.AgentStatus)
SetAgents updates the agent list.
func (*AgentList) SetFocused ¶
SetFocused sets the focus state.
func (*AgentList) SetNeedsAttention ¶
SetNeedsAttention updates which agents have pending approvals.
func (*AgentList) SetSelected ¶
SetSelected sets the selection index.
func (*AgentList) SetSpinnerFrame ¶
SetSpinnerFrame updates the current spinner animation frame.
type ChatView ¶
type ChatView struct {
// contains filtered or unexported fields
}
ChatView displays chat entries for a selected agent in a conversational format.
func (*ChatView) AppendEntry ¶
func (v *ChatView) AppendEntry(entry daemon.ChatEntryDTO)
AppendEntry adds a chat entry to the view.
func (*ChatView) ClearAgent ¶
func (v *ChatView) ClearAgent()
ClearAgent clears the current agent view.
func (*ChatView) ClearPlanProjectSelection ¶
func (v *ChatView) ClearPlanProjectSelection()
ClearPlanProjectSelection clears plan project selection mode.
func (*ChatView) ClearPlanPromptMode ¶
func (v *ChatView) ClearPlanPromptMode()
ClearPlanPromptMode clears plan prompt mode.
func (*ChatView) ClearSupervisorProjectSelection ¶
func (v *ChatView) ClearSupervisorProjectSelection()
ClearSupervisorProjectSelection clears supervisor project selection mode.
func (*ChatView) GetSelectedAnswer ¶
GetSelectedAnswer returns the selected answer for the current question. Returns the option label, or "" for "Other" (which requires freeform input).
func (*ChatView) HasPendingPermission ¶
HasPendingPermission returns whether there's a pending permission request.
func (*ChatView) HasPendingUserQuestion ¶
HasPendingUserQuestion returns whether there's a pending user question.
func (*ChatView) PendingPermissionID ¶
PendingPermissionID returns the ID of the pending permission request, or empty string.
func (*ChatView) PendingUserQuestionID ¶
PendingUserQuestionID returns the ID of the pending user question, or empty string.
func (*ChatView) QuestionMoveDown ¶
func (v *ChatView) QuestionMoveDown()
QuestionMoveDown moves the selection down in the user question options.
func (*ChatView) QuestionMoveUp ¶
func (v *ChatView) QuestionMoveUp()
QuestionMoveUp moves the selection up in the user question options.
func (*ChatView) ScrollDown ¶
ScrollDown scrolls the viewport down.
func (*ChatView) ScrollToBottom ¶
func (v *ChatView) ScrollToBottom()
ScrollToBottom scrolls to the bottom.
func (*ChatView) SetAbortConfirming ¶
SetAbortConfirming sets the abort confirmation state.
func (*ChatView) SetEntries ¶
func (v *ChatView) SetEntries(entries []daemon.ChatEntryDTO)
SetEntries merges historical entries with any streaming entries that may have arrived while the history was being fetched. This prevents a race condition where switching agents triggers a history fetch, but streaming events arrive before the history response - without merging, those streaming events would be lost when SetEntries replaces v.entries.
func (*ChatView) SetFocused ¶
SetFocused sets the focus state.
func (*ChatView) SetInputView ¶
SetInputView sets the rendered input line view to display.
func (*ChatView) SetPendingPermission ¶
func (v *ChatView) SetPendingPermission(req *daemon.PermissionRequest)
SetPendingPermission sets the pending permission request for this chat view.
func (*ChatView) SetPendingUserQuestion ¶
func (v *ChatView) SetPendingUserQuestion(question *daemon.UserQuestion)
SetPendingUserQuestion sets the pending user question for this chat view.
func (*ChatView) SetPlanProjectSelection ¶
SetPlanProjectSelection sets the plan project selection mode state.
func (*ChatView) SetPlanProjectSelectionWithFilter ¶
func (v *ChatView) SetPlanProjectSelectionWithFilter(projects []string, selectedIndex int, filter string)
SetPlanProjectSelectionWithFilter sets the plan project selection mode state with a filter.
func (*ChatView) SetPlanPromptMode ¶
SetPlanPromptMode sets the plan prompt mode state.
func (*ChatView) SetSupervisorProjectSelection ¶
func (v *ChatView) SetSupervisorProjectSelection(projects []string, selectedIndex int, running map[string]bool)
SetSupervisorProjectSelection sets the supervisor project selection mode state.
type EventStreamer ¶
type EventStreamer interface {
StreamEvents(projects []string) (<-chan daemon.EventResult, error)
}
EventStreamer is the interface for streaming events from the daemon.
type Header ¶
type Header struct {
// contains filtered or unexported fields
}
Header displays the fab TUI header with branding and status info.
func (*Header) SetAgentCounts ¶
SetAgentCounts updates the agent statistics.
func (*Header) SetConnectionState ¶
func (h *Header) SetConnectionState(state connectionState)
SetConnectionState updates the connection state display.
type HelpBar ¶
type HelpBar struct {
// contains filtered or unexported fields
}
HelpBar displays context-sensitive keyboard shortcuts at the bottom of the TUI.
func (*HelpBar) SetModeState ¶
SetModeState updates the help bar's mode state for rendering appropriate shortcuts.
type InputLine ¶
type InputLine struct {
// contains filtered or unexported fields
}
InputLine is a text input component for sending input to agents.
func (*InputLine) AddToHistory ¶
AddToHistory adds the given input to history if non-empty.
func (*InputLine) ContentHeight ¶
ContentHeight returns the height needed to display the current content, including soft-wrapped lines. Minimum 1, maximum maxInputHeight.
func (*InputLine) HistoryDown ¶
HistoryDown navigates to the next (newer) history entry. Returns true if the input was changed.
func (*InputLine) HistoryUp ¶
HistoryUp navigates to the previous (older) history entry. Returns true if the input was changed.
func (*InputLine) InsertNewline ¶
func (i *InputLine) InsertNewline()
InsertNewline inserts a newline at the cursor position (for shift+enter).
func (*InputLine) ResetHistoryNavigation ¶
func (i *InputLine) ResetHistoryNavigation()
ResetHistoryNavigation resets history browsing state.
func (*InputLine) SetFocused ¶
SetFocused sets the focus state.
func (*InputLine) SetPlaceholder ¶
SetPlaceholder sets the placeholder text.
type KeyBindings ¶
type KeyBindings struct {
// Global keys
Quit key.Binding
Tab key.Binding
FocusChat key.Binding
Reconnect key.Binding
// Navigation keys
Up key.Binding
Down key.Binding
Top key.Binding
Bottom key.Binding
PageUp key.Binding
PageDown key.Binding
// Action keys
Approve key.Binding
Reject key.Binding
Abort key.Binding
Plan key.Binding
Supervisor key.Binding
// Input keys
Submit key.Binding
Cancel key.Binding
HistoryUp key.Binding
HistoryDown key.Binding
NewLine key.Binding
}
KeyBindings defines all keyboard shortcuts for the TUI.
func DefaultKeyBindings ¶
func DefaultKeyBindings() KeyBindings
DefaultKeyBindings returns the default key bindings.
type Mode ¶
type Mode int
Mode represents the current interaction mode of the TUI. Only one mode can be active at a time, providing clear state management.
const ( // ModeNormal is the default mode for navigating the TUI. ModeNormal Mode = iota // ModeInput means the user is typing in the input line. ModeInput // ModeAbortConfirm means the user is being asked to confirm an abort. ModeAbortConfirm // ModeUserQuestion means the user is answering a question from Claude. ModeUserQuestion // ModePlanProjectSelect means the user is selecting a project for planning. ModePlanProjectSelect // ModePlanPrompt means the user is entering a planning prompt. ModePlanPrompt // ModeSupervisorProjectSelect means the user is selecting a project for supervisor start. ModeSupervisorProjectSelect )
type ModeState ¶
type ModeState struct {
// Mode is the current interaction mode (normal, input, abort confirmation, user question).
Mode Mode
// Focus indicates which panel is currently focused when in normal mode.
Focus Focus
// AbortAgentID is the agent being aborted (only valid when Mode == ModeAbortConfirm).
AbortAgentID string
// HasPendingPermission indicates if there's a permission request awaiting approval.
HasPendingPermission bool
// HasPendingUserQuestion indicates if there's a user question awaiting response.
HasPendingUserQuestion bool
// PlanProject is the selected project for planning (only valid when Mode == ModePlanPrompt).
PlanProject string
// PlanProjects is the list of available projects for planning (only valid when Mode == ModePlanProjectSelect).
PlanProjects []string
// PlanProjectIndex is the currently selected project index (only valid when Mode == ModePlanProjectSelect).
PlanProjectIndex int
// PlanProjectFilter is the current filter text for fuzzy matching (only valid when Mode == ModePlanProjectSelect).
PlanProjectFilter string
// PlanProjectFiltered is the list of projects that match the filter (only valid when Mode == ModePlanProjectSelect).
PlanProjectFiltered []string
// SupervisorProjects is the list of available projects for supervisor (only valid when Mode == ModeSupervisorProjectSelect).
SupervisorProjects []string
// SupervisorProjectIndex is the currently selected project index (only valid when Mode == ModeSupervisorProjectSelect).
SupervisorProjectIndex int
// SupervisorProjectFilter is the current filter text for fuzzy matching (only valid when Mode == ModeSupervisorProjectSelect).
SupervisorProjectFilter string
// SupervisorProjectFiltered is the list of projects that match the filter (only valid when Mode == ModeSupervisorProjectSelect).
SupervisorProjectFiltered []string
// SupervisorProjectRunning tracks which projects have running supervision.
SupervisorProjectRunning map[string]bool
}
ModeState centralizes all mode and focus-related state for the TUI. This provides a single source of truth for the current interaction state.
func NewModeState ¶
func NewModeState() ModeState
NewModeState creates a new ModeState with default values.
func (*ModeState) CancelAbort ¶
CancelAbort cancels the abort confirmation and returns to normal mode. Returns an error if not in abort confirmation mode.
func (*ModeState) CancelPlanProjectSelect ¶
CancelPlanProjectSelect cancels project selection and returns to normal mode.
func (*ModeState) CancelPlanPromptMode ¶
CancelPlanPromptMode cancels plan prompt mode without completing.
func (*ModeState) CancelSupervisorProjectSelect ¶
CancelSupervisorProjectSelect cancels project selection and returns to normal mode.
func (*ModeState) ConfirmAbort ¶
ConfirmAbort confirms the abort and returns to normal mode. Returns the agent ID that was being aborted, or an error if not in abort mode.
func (*ModeState) CycleFocus ¶
CycleFocus advances focus to the next panel in the cycle. AgentList -> ChatView -> AgentList InputLine is not part of the cycle - it's accessed via the FocusChat key binding. Returns the new focus value, or an error if not in normal mode.
func (*ModeState) EnterAbortConfirm ¶
EnterAbortConfirm transitions to abort confirmation mode for the given agent. Returns an error if agentID is empty or already in abort confirmation.
func (*ModeState) EnterInputMode ¶
EnterInputMode transitions to input mode. Returns an error if already in input mode or in abort confirmation.
func (*ModeState) EnterPlanProjectSelect ¶
EnterPlanProjectSelect transitions to plan project selection mode. projects is the list of available projects to choose from.
func (*ModeState) EnterSupervisorProjectSelect ¶
EnterSupervisorProjectSelect transitions to supervisor project selection mode. projects is the list of available projects to choose from. running is a map of project names that have running supervision.
func (*ModeState) EnterUserQuestionMode ¶
EnterUserQuestionMode transitions to user question mode. Returns an error if already in user question mode or in another modal mode.
func (*ModeState) ExitInputMode ¶
ExitInputMode returns from input mode to normal mode. Returns an error if not currently in input mode.
func (*ModeState) ExitPlanPromptMode ¶
ExitPlanPromptMode returns from plan prompt mode to normal mode. Returns the selected project name, or an error if not in plan prompt mode.
func (*ModeState) ExitUserQuestionMode ¶
ExitUserQuestionMode returns from user question mode to normal mode. Returns an error if not currently in user question mode.
func (*ModeState) IsAbortConfirming ¶
IsAbortConfirming returns true if in abort confirmation mode.
func (*ModeState) IsInputting ¶
IsInputting returns true if in input mode.
func (*ModeState) IsPlanProjectSelect ¶
IsPlanProjectSelect returns true if in plan project selection mode.
func (*ModeState) IsPlanPrompt ¶
IsPlanPrompt returns true if in plan prompt mode.
func (*ModeState) IsSupervisorProjectSelect ¶
IsSupervisorProjectSelect returns true if in supervisor project selection mode.
func (*ModeState) IsUserQuestion ¶
IsUserQuestion returns true if in user question mode.
func (*ModeState) NeedsApproval ¶
NeedsApproval returns true if there's any pending approval.
func (*ModeState) PlanProjectAppendFilter ¶
PlanProjectAppendFilter appends a character to the filter.
func (*ModeState) PlanProjectBackspaceFilter ¶
func (s *ModeState) PlanProjectBackspaceFilter()
PlanProjectBackspaceFilter removes the last character from the filter.
func (*ModeState) PlanProjectFilterState ¶
PlanProjectFilterState returns the current filter string.
func (*ModeState) PlanProjectSelectDown ¶
func (s *ModeState) PlanProjectSelectDown()
PlanProjectSelectDown moves the selection down in the project list.
func (*ModeState) PlanProjectSelectUp ¶
func (s *ModeState) PlanProjectSelectUp()
PlanProjectSelectUp moves the selection up in the project list.
func (*ModeState) PlanProjectSetFilter ¶
PlanProjectSetFilter updates the filter and recomputes the filtered list.
func (*ModeState) SelectPlanProject ¶
SelectPlanProject selects the current project and transitions to prompt mode.
func (*ModeState) SelectSupervisorProject ¶
SelectSupervisorProject selects the current project and returns to normal mode. Returns the project name and whether it was running (to determine start vs stop).
func (*ModeState) SelectedPlanProject ¶
SelectedPlanProject returns the selected project name and the filtered list of projects.
func (*ModeState) SelectedSupervisorProject ¶
SelectedSupervisorProject returns the filtered list of projects and the current index.
func (*ModeState) SetFocus ¶
SetFocus changes the focus panel. Only valid in normal mode. Returns an error if called in a mode that doesn't support focus changes.
func (*ModeState) SetPendingApprovals ¶
SetPendingApprovals updates the pending approval state. The second parameter (hasAction) is kept for API compatibility but ignored.
func (*ModeState) SupervisorProjectAppendFilter ¶
SupervisorProjectAppendFilter appends a character to the filter.
func (*ModeState) SupervisorProjectBackspaceFilter ¶
func (s *ModeState) SupervisorProjectBackspaceFilter()
SupervisorProjectBackspaceFilter removes the last character from the filter.
func (*ModeState) SupervisorProjectFilterState ¶
SupervisorProjectFilterState returns the current filter string.
func (*ModeState) SupervisorProjectSelectDown ¶
func (s *ModeState) SupervisorProjectSelectDown()
SupervisorProjectSelectDown moves the selection down in the project list.
func (*ModeState) SupervisorProjectSelectUp ¶
func (s *ModeState) SupervisorProjectSelectUp()
SupervisorProjectSelectUp moves the selection up in the project list.
func (*ModeState) SupervisorProjectSetFilter ¶
SupervisorProjectSetFilter updates the filter and recomputes the filtered list.
type Model ¶
type Model struct {
// contains filtered or unexported fields
}
Model is the main Bubbletea model for the fab TUI.
func NewWithClient ¶
func NewWithClient(client daemon.TUIClient, opts *TUIOptions) Model
NewWithClient creates a new TUI model with a pre-connected daemon client.
type TUIOptions ¶
type TUIOptions struct {
// InitialAgentID specifies an agent to select on startup.
// If empty, the first agent in the list will be selected.
InitialAgentID string
}
TUIOptions configures the TUI behavior.