Documentation
¶
Overview ¶
Package tui provides terminal UI utilities.
Package tui provides terminal UI utilities.
Package tui provides terminal UI utilities.
Package tui provides terminal UI utilities.
Package tui provides terminal UI utilities.
Package tui provides terminal UI utilities.
Package tui provides the terminal user interface for stackit.
It handles:
- Interactive prompts and selections (using survey and bubbletea)
- Terminal styling and colors (using lipgloss)
- Progress indicators and UI components
Index ¶
- Constants
- Variables
- func BuildFullAnnotation(eng engine.Engine, branch engine.Branch, enrichment *AnnotationEnrichment) tree.BranchAnnotation
- func CheckInteractiveAllowed() error
- func GetBranchAnnotation(eng engine.BranchReader, branch engine.Branch) tree.BranchAnnotation
- func GetEmptyWorktrees(eng engine.Engine) map[string]*engine.WorktreeInfo
- func GetMinimalAnnotationWithWorktreeAndEmpty(eng engine.Engine, branch engine.Branch, wtData *WorktreeData) tree.BranchAnnotation
- func IsTTY() bool
- func NewBranchSelectModel(message string, choices []BranchChoice, initialIndex int) tea.Model
- func NewConfirmModel(prompt string, defaultValue bool) tea.Model
- func NewReorderModel(branches []string, trunk string) tea.Model
- func NewSelectModel(title string, options []SelectOption, defaultIndex int) tea.Model
- func NewStackTreeRenderer(eng engine.BranchReader) *tree.StackTreeRenderer
- func NewStackTreeRendererWithEmptyWorktrees(eng engine.BranchReader, emptyWorktrees map[string]bool) *tree.StackTreeRenderer
- func NewStackTreeRendererWithFilter(eng engine.BranchReader, filter func(string) bool) *tree.StackTreeRenderer
- func NewStackTreeRendererWithOptions(eng engine.BranchReader, strategy engine.SortStrategy, ...) *tree.StackTreeRenderer
- func NewStackTreeRendererWithStrategy(eng engine.BranchReader, strategy engine.SortStrategy, ...) *tree.StackTreeRenderer
- func NewTextInputModel(prompt, defaultValue string) tea.Model
- func OpenEditor(initialContent, filenamePattern string) (string, error)
- func PromptBranchCheckout(branches []engine.Branch, eng engine.BranchReader) (string, error)
- func PromptBranchSelection(message string, choices []BranchChoice, initialIndex int) (string, error)
- func PromptLogSelect(ctx context.Context, eng engine.Engine, ghClient github.Client, ...) (string, error)
- func PromptMultiSelect(title string, options []string) ([]string, error)
- func PromptMultiSelectWithDefaults(title string, options []string, preSelected []bool) ([]string, error)
- func PromptSelect(title string, options []SelectOption, defaultIndex int) (string, error)
- func PromptSelectHunks(hunks []git.Hunk) ([]git.Hunk, error)
- func PromptTextInput(prompt, defaultValue string) (string, error)
- func RegisterStory(story Story)
- func RenderFlattenPreview(preview FlattenPreviewData) string
- func RenderMovePreviewSimple(preview MovePreviewData) string
- func RunReorderTUI(branches []string, trunk string) ([]string, error)
- func RunSubmitTUI(items []submit.Item, submitFunc func(idx int) tea.Cmd) error
- func RunSubmitTUISimple(items []submit.Item, submitFunc func(idx int) (string, error), ...) error
- func SafeCmd(name string, logger output.Logger, cmd tea.Cmd) tea.Cmd
- func SafeCmdFunc(name string, logger output.Logger, fn func() tea.Msg) tea.Cmd
- func SetInteractive(interactive bool)
- type AllDoneMsg
- type AnnotationEnrichment
- type BaseModel
- type BranchChoice
- type CompleteMsg
- type Direction
- type DirectionSelectModel
- func (m *DirectionSelectModel) Back() bool
- func (m *DirectionSelectModel) Direction() Direction
- func (m *DirectionSelectModel) Err() error
- func (m *DirectionSelectModel) Init() tea.Cmd
- func (m *DirectionSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (m *DirectionSelectModel) View() tea.View
- type FileGroup
- type FlattenExcludedBranch
- type FlattenPlannedMove
- type FlattenPreviewData
- type Handler
- type HunkItem
- type HunkSelectorModel
- func (m *HunkSelectorModel) Err() error
- func (m *HunkSelectorModel) Init() tea.Cmd
- func (m *HunkSelectorModel) Reset()
- func (m *HunkSelectorModel) SelectedHunks() []git.Hunk
- func (m *HunkSelectorModel) SetHunks(hunks []git.Hunk)
- func (m *HunkSelectorModel) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (m *HunkSelectorModel) View() tea.View
- type LogMode
- type LogModel
- type LogOptions
- type MessageRecorder
- type MockRunner
- func (m *MockRunner) Cleanup()
- func (m *MockRunner) IsHealthy() bool
- func (m *MockRunner) MessageCount() int
- func (m *MockRunner) Messages() []tea.Msg
- func (m *MockRunner) Pause()
- func (m *MockRunner) Reset()
- func (m *MockRunner) Resume()
- func (m *MockRunner) Send(msg tea.Msg)
- func (m *MockRunner) Start()
- func (m *MockRunner) Wait()
- type MoveModel
- type MoveModelConfig
- type MovePreviewData
- type MoveResult
- type MoveValidation
- type MoveValidator
- type PanicError
- type PhaseHandler
- type PhaseMsg
- type ProgressHandler
- type ProgressMsg
- type PromptHandler
- type ReadySignaler
- type Runner
- func (r *Runner) Cleanup()
- func (r *Runner) Context() context.Context
- func (r *Runner) IsHealthy() bool
- func (r *Runner) IsRunning() bool
- func (r *Runner) MustSend(msg tea.Msg)
- func (r *Runner) Pause()
- func (r *Runner) Resume()
- func (r *Runner) Send(msg tea.Msg)
- func (r *Runner) SendWithTimeout(msg tea.Msg, timeout time.Duration) error
- func (r *Runner) Start()
- func (r *Runner) Wait()
- type SelectOption
- type SelectionValidation
- type Sender
- type Status
- type Story
- type SubmitResultMsg
- type SubmitTUIModel
- type WorktreeData
Constants ¶
const ( StatusPending = core.StatusPending StatusActive = core.StatusActive StatusDone = core.StatusDone StatusError = core.StatusError StatusSkipped = core.StatusSkipped StatusWaiting = core.StatusWaiting )
Status constants re-exported from core for backwards compatibility.
const ( KeyCtrlC = core.KeyCtrlC KeyQuit = core.KeyQuit KeyEsc = core.KeyEsc KeyEnter = core.KeyEnter KeyUp = core.KeyUp KeyDown = core.KeyDown KeyTab = core.KeyTab )
Key constants re-exported from core for backwards compatibility.
Variables ¶
var ErrInteractiveDisabled = fmt.Errorf("interactive prompts are disabled (running with --no-interactive or not in a TTY)")
ErrInteractiveDisabled is returned when interactive prompts are disabled
var PromptConfirm = func(prompt string, defaultValue bool) (bool, error) { if err := CheckInteractiveAllowed(); err != nil { return false, err } m := confirmModel{ prompt: prompt, choice: defaultValue, help: help.New(), keys: confirmPromptKeys, } p := tea.NewProgram(m, tea.WithInput(os.Stdin), tea.WithOutput(os.Stdout)) model, err := p.Run() if err != nil { return false, err } if finalModel, ok := model.(confirmModel); ok { if finalModel.err != nil { return false, finalModel.err } return finalModel.choice, nil } return false, fmt.Errorf("unexpected model type") }
PromptConfirm prompts the user for yes/no confirmation
var Stories = []Story{}
Stories is a registry of all component stories
Functions ¶
func BuildFullAnnotation ¶
func BuildFullAnnotation(eng engine.Engine, branch engine.Branch, enrichment *AnnotationEnrichment) tree.BranchAnnotation
BuildFullAnnotation returns a fully populated BranchAnnotation including git operations (SHA, commits, diff stats), CI status, review status, and worktree info. Pass nil for enrichment to get just the base annotation without CI/worktree enrichment.
func CheckInteractiveAllowed ¶
func CheckInteractiveAllowed() error
CheckInteractiveAllowed returns an error if interactive mode is disabled
func GetBranchAnnotation ¶
func GetBranchAnnotation(eng engine.BranchReader, branch engine.Branch) tree.BranchAnnotation
GetBranchAnnotation returns a tree.BranchAnnotation populated with standard branch metadata. This includes git operations (SHA, commit count, diff stats) which may be slow.
func GetEmptyWorktrees ¶
func GetEmptyWorktrees(eng engine.Engine) map[string]*engine.WorktreeInfo
GetEmptyWorktrees returns a map of worktree anchor branch names to their WorktreeInfo for worktrees that have no child branches (empty worktrees).
func GetMinimalAnnotationWithWorktreeAndEmpty ¶
func GetMinimalAnnotationWithWorktreeAndEmpty(eng engine.Engine, branch engine.Branch, wtData *WorktreeData) tree.BranchAnnotation
GetMinimalAnnotationWithWorktreeAndEmpty returns minimal annotations plus worktree info, with support for marking empty worktrees. This is used for fast initial rendering before full data is loaded. Only includes cached/instant fields - no git or network calls.
func IsTTY ¶
func IsTTY() bool
IsTTY returns true if we can use a TTY for interactive TUI. Re-export from utils for backward compatibility.
func NewBranchSelectModel ¶
func NewBranchSelectModel(message string, choices []BranchChoice, initialIndex int) tea.Model
NewBranchSelectModel creates a tea.Model for a branch selection prompt (used by stories/demo)
func NewConfirmModel ¶
NewConfirmModel creates a tea.Model for a confirmation prompt (used by stories/demo)
func NewReorderModel ¶
NewReorderModel creates a tea.Model for a reorder prompt (used by stories/demo)
func NewSelectModel ¶
func NewSelectModel(title string, options []SelectOption, defaultIndex int) tea.Model
NewSelectModel creates a tea.Model for a selection prompt (used by stories/demo)
func NewStackTreeRenderer ¶
func NewStackTreeRenderer(eng engine.BranchReader) *tree.StackTreeRenderer
NewStackTreeRenderer creates a tree renderer configured for the current engine state using the SMART sorting strategy (active path hoisting + newest first).
func NewStackTreeRendererWithEmptyWorktrees ¶
func NewStackTreeRendererWithEmptyWorktrees(eng engine.BranchReader, emptyWorktrees map[string]bool) *tree.StackTreeRenderer
NewStackTreeRendererWithEmptyWorktrees creates a tree renderer that shows empty worktree anchors
func NewStackTreeRendererWithFilter ¶
func NewStackTreeRendererWithFilter(eng engine.BranchReader, filter func(string) bool) *tree.StackTreeRenderer
NewStackTreeRendererWithFilter creates a tree renderer with a filter function
func NewStackTreeRendererWithOptions ¶
func NewStackTreeRendererWithOptions(eng engine.BranchReader, strategy engine.SortStrategy, filter func(string) bool, emptyWorktrees map[string]bool) *tree.StackTreeRenderer
NewStackTreeRendererWithOptions creates a tree renderer with all options
func NewStackTreeRendererWithStrategy ¶
func NewStackTreeRendererWithStrategy(eng engine.BranchReader, strategy engine.SortStrategy, filter func(string) bool) *tree.StackTreeRenderer
NewStackTreeRendererWithStrategy creates a tree renderer with a specific sorting strategy and optional filter
func NewTextInputModel ¶
NewTextInputModel creates a tea.Model for a text input prompt (used by stories/demo)
func OpenEditor ¶
OpenEditor opens the user's preferred editor with the given initial content. It returns the edited content or an error.
func PromptBranchCheckout ¶
PromptBranchCheckout shows an interactive branch selector for checkout. It takes a list of branches and the engine context, formats them using tree rendering, and presents them for selection.
func PromptBranchSelection ¶
func PromptBranchSelection(message string, choices []BranchChoice, initialIndex int) (string, error)
PromptBranchSelection prompts the user to select a branch
func PromptLogSelect ¶
func PromptLogSelect(ctx context.Context, eng engine.Engine, ghClient github.Client, opts LogOptions) (string, error)
PromptLogSelect runs the interactive log in selection mode and returns the selected branch name
func PromptMultiSelect ¶
PromptMultiSelect prompts the user to select multiple items from a list
func PromptMultiSelectWithDefaults ¶
func PromptMultiSelectWithDefaults(title string, options []string, preSelected []bool) ([]string, error)
PromptMultiSelectWithDefaults prompts the user to select multiple items from a list with optional pre-selected items. If preSelected is nil, nothing is selected by default.
func PromptSelect ¶
func PromptSelect(title string, options []SelectOption, defaultIndex int) (string, error)
PromptSelect prompts the user to select from a list of options
func PromptSelectHunks ¶
PromptSelectHunks shows an interactive hunk selector and returns the selected hunks
func PromptTextInput ¶
PromptTextInput prompts the user for text input
func RenderFlattenPreview ¶
func RenderFlattenPreview(preview FlattenPreviewData) string
RenderFlattenPreview renders a flatten preview showing: - List of branches that will be moved and their new parents - Count of branches that will stay unchanged - Conflict status
func RenderMovePreviewSimple ¶
func RenderMovePreviewSimple(preview MovePreviewData) string
RenderMovePreviewSimple renders a simplified move preview showing: - Current location (dimmed) - New location (highlighted) - Conflict status
func RunReorderTUI ¶
RunReorderTUI runs the reorder TUI and returns the new order trunk is displayed at the bottom but is not selectable or reorderable
func RunSubmitTUI ¶
RunSubmitTUI runs the submit TUI and returns when complete
func RunSubmitTUISimple ¶
func RunSubmitTUISimple(items []submit.Item, submitFunc func(idx int) (string, error), splog output.Output) error
RunSubmitTUISimple runs a simple non-interactive version for non-TTY environments
func SafeCmd ¶
SafeCmd wraps a tea.Cmd with panic recovery. If the command panics, it logs the error and returns a PanicError message. This is useful for commands that perform IO or call external APIs.
func SafeCmdFunc ¶
SafeCmdFunc wraps a function that returns tea.Msg with panic recovery. If the function panics, it logs the error and returns a PanicError message.
func SetInteractive ¶
func SetInteractive(interactive bool)
SetInteractive sets whether the TUI should be interactive. Re-export from utils for backward compatibility. This function is thread-safe and can be called from concurrent goroutines.
Types ¶
type AnnotationEnrichment ¶
type AnnotationEnrichment struct {
CIStatuses map[string]*github.CheckStatus
EmptyWorktrees map[string]*engine.WorktreeInfo
WorktreeByStackRoot map[string]*engine.WorktreeInfo
}
AnnotationEnrichment holds pre-fetched data for enriching branch annotations. This allows CI statuses and worktree info to be computed once and shared across all branches, avoiding redundant lookups.
type BaseModel ¶
BaseModel is an alias to core.BaseModel for backwards compatibility. New code should import from tui/core directly to avoid import cycles.
type BranchChoice ¶
type BranchChoice struct {
Display string // What to show (may include tree visualization)
Value string // Actual branch name
}
BranchChoice represents a branch option in a selection prompt
type CompleteMsg ¶
type CompleteMsg struct {
Success bool // True if operation succeeded
Summary string // Summary message to display
Error error // Error if Success is false
}
CompleteMsg signals operation completion. Use this to indicate that the overall operation is done.
type Direction ¶
type Direction string
Direction represents where to place a new branch
Direction constants for split operations.
func PromptDirectionSelect ¶
func PromptDirectionSelect(eng engine.BranchReader, currentBranch, parentBranch string, children []string) (Direction, error)
PromptDirectionSelect shows an interactive direction selector and returns the chosen direction
type DirectionSelectModel ¶
type DirectionSelectModel struct {
// contains filtered or unexported fields
}
DirectionSelectModel is a bubbletea model for selecting split direction
func NewDirectionSelectModel ¶
func NewDirectionSelectModel(eng engine.BranchReader, currentBranch, parentBranch string, children []string) *DirectionSelectModel
NewDirectionSelectModel creates a model for selecting split direction
func (*DirectionSelectModel) Back ¶
func (m *DirectionSelectModel) Back() bool
Back returns true if the user pressed back
func (*DirectionSelectModel) Direction ¶
func (m *DirectionSelectModel) Direction() Direction
Direction returns the selected direction
func (*DirectionSelectModel) Err ¶
func (m *DirectionSelectModel) Err() error
Err returns any error that occurred
func (*DirectionSelectModel) Init ¶
func (m *DirectionSelectModel) Init() tea.Cmd
Init implements tea.Model.
func (*DirectionSelectModel) View ¶
func (m *DirectionSelectModel) View() tea.View
View implements tea.Model.
type FileGroup ¶
type FileGroup struct {
File string
Hunks []int // Indices into the items slice
Binary bool // Is this a binary file?
}
FileGroup groups hunks by file for rendering
type FlattenExcludedBranch ¶
type FlattenExcludedBranch struct {
Branch string // Branch name
Reason string // Why it was kept in place
}
FlattenExcludedBranch represents a branch that was kept in place due to code dependencies. This is a local struct to avoid import cycles with the actions/flatten package.
type FlattenPlannedMove ¶
type FlattenPlannedMove struct {
Branch string // Branch being moved
OldParent string // Current parent branch
NewParent string // Target parent branch (closer to trunk)
}
FlattenPlannedMove represents a single branch move in the flatten plan. This is a local struct to avoid import cycles with the actions/flatten package.
type FlattenPreviewData ¶
type FlattenPreviewData struct {
Moves []FlattenPlannedMove // Branches that will be moved
UnchangedCount int // Number of branches that won't change
ExcludedBranches []FlattenExcludedBranch // Branches excluded due to conflicts
}
FlattenPreviewData contains the data needed to render a flatten preview. This is a local struct to avoid import cycles with the actions/flatten package.
type Handler ¶
type Handler interface {
// IsInteractive returns true if this handler supports interactive prompts.
// Interactive handlers can pause the TUI for user input.
IsInteractive() bool
// Cleanup performs any necessary cleanup. Safe to call multiple times.
// For interactive handlers, this typically delegates to the Runner.
Cleanup()
}
Handler is the base interface for all TUI handlers. Handlers abstract the difference between interactive (TTY) and non-interactive output.
type HunkItem ¶
type HunkItem struct {
Hunk git.Hunk
Selected bool
Expanded bool // Manual expand/collapse override
Splittable bool // Can this hunk be split further?
}
HunkItem represents a single hunk in the selector
type HunkSelectorModel ¶
type HunkSelectorModel struct {
core.BaseModel // Embedded for ReadySignaler interface
// contains filtered or unexported fields
}
HunkSelectorModel is a bubbletea model for selecting hunks. It embeds core.BaseModel for standard lifecycle handling.
func NewHunkSelectorModel ¶
func NewHunkSelectorModel(hunks []git.Hunk) *HunkSelectorModel
NewHunkSelectorModel creates a new hunk selector model
func (*HunkSelectorModel) Err ¶
func (m *HunkSelectorModel) Err() error
Err returns any error that occurred
func (*HunkSelectorModel) Init ¶
func (m *HunkSelectorModel) Init() tea.Cmd
Init implements tea.Model
func (*HunkSelectorModel) Reset ¶
func (m *HunkSelectorModel) Reset()
Reset resets the model state for reuse
func (*HunkSelectorModel) SelectedHunks ¶
func (m *HunkSelectorModel) SelectedHunks() []git.Hunk
SelectedHunks returns the hunks that were selected
func (*HunkSelectorModel) SetHunks ¶
func (m *HunkSelectorModel) SetHunks(hunks []git.Hunk)
SetHunks replaces the hunks in the model for reuse in subsequent selections. This allows the hunk selector to be reused in a loop without creating new models.
func (*HunkSelectorModel) View ¶
func (m *HunkSelectorModel) View() tea.View
View implements tea.Model
type LogModel ¶
type LogModel struct {
// contains filtered or unexported fields
}
LogModel is the bubbletea model for the interactive log
func NewLogModel ¶
func NewLogModel(ctx context.Context, eng engine.Engine, ghClient github.Client, opts LogOptions) *LogModel
NewLogModel creates a new LogModel
func (*LogModel) SetAltScreen ¶
SetAltScreen sets whether the model should use alt screen mode
type LogOptions ¶
type LogOptions struct {
Style string
ShowUntracked bool
Exclude map[string]bool // Branches to exclude from selection
NonSelectable map[string]bool // Branches visible but not selectable (cursor skips them)
AnnotationOverrides map[string]tree.BranchAnnotation // Override annotations (e.g., add custom labels)
Logger output.Logger // Optional logger for IO timing diagnostics
Header string // Custom header text for selection mode (e.g., "Select new parent for branch X")
SkipEnrichment bool // Skip background GitHub/git enrichment for faster startup
Inline bool // Run inline without alt-screen (doesn't take over terminal)
// ValidateSelection is called (with debounce) when selection changes to validate the current selection.
// If provided, the result is displayed in the UI footer.
ValidateSelection func(branchName string) *SelectionValidation
}
LogOptions repeated here to avoid circular dependency if needed, but we'll probably use actions.LogOptions
type MessageRecorder ¶
type MessageRecorder struct {
// contains filtered or unexported fields
}
MessageRecorder records messages for test assertions. It can be used to verify that specific messages were sent during tests.
func NewMessageRecorder ¶
func NewMessageRecorder() *MessageRecorder
NewMessageRecorder creates a new MessageRecorder.
func (*MessageRecorder) Count ¶
func (r *MessageRecorder) Count() int
Count returns the number of recorded messages.
func (*MessageRecorder) HasMessage ¶
func (r *MessageRecorder) HasMessage(predicate func(tea.Msg) bool) bool
HasMessage returns true if any recorded message matches the predicate.
func (*MessageRecorder) Messages ¶
func (r *MessageRecorder) Messages() []tea.Msg
Messages returns a copy of all recorded messages.
func (*MessageRecorder) Record ¶
func (r *MessageRecorder) Record(msg tea.Msg)
Record adds a message to the recorder.
func (*MessageRecorder) Reset ¶
func (r *MessageRecorder) Reset()
Reset clears all recorded messages.
type MockRunner ¶
type MockRunner struct {
// contains filtered or unexported fields
}
MockRunner is a test double for Runner. It records all messages sent to it and provides methods to inspect them.
func (*MockRunner) IsHealthy ¶
func (m *MockRunner) IsHealthy() bool
IsHealthy returns true if the runner has been started and not stopped.
func (*MockRunner) MessageCount ¶
func (m *MockRunner) MessageCount() int
MessageCount returns the number of recorded messages.
func (*MockRunner) Messages ¶
func (m *MockRunner) Messages() []tea.Msg
Messages returns a copy of all recorded messages.
func (*MockRunner) Reset ¶
func (m *MockRunner) Reset()
Reset clears all recorded messages and state.
func (*MockRunner) Send ¶
func (m *MockRunner) Send(msg tea.Msg)
Send records a message for later inspection.
type MoveModel ¶
type MoveModel struct {
// contains filtered or unexported fields
}
MoveModel is the bubbletea model for the interactive move flow
func NewMoveModel ¶
func NewMoveModel(eng engine.Engine, config MoveModelConfig) *MoveModel
NewMoveModel creates a new MoveModel for interactive branch selection
func (*MoveModel) Result ¶
func (m *MoveModel) Result() MoveResult
Result returns the result of the move selection
type MoveModelConfig ¶
type MoveModelConfig struct {
SourceBranch string // Branch being moved
Descendants []engine.Branch // Descendants that will be restacked
OldParent *engine.Branch // Current parent branch
OldParentRev string // Current parent revision for rebase specs
Validator MoveValidator // Validation function for conflict checking
}
MoveModelConfig contains configuration for the move model
type MovePreviewData ¶
type MovePreviewData struct {
SourceBranch string // Branch being moved
OldParent string // Current parent branch
NewParent string // Target parent branch
Commits []string // Commit subjects that will be moved
Descendants []string // Descendant branches that will be restacked
HasConflicts bool // Whether the move will cause conflicts
ConflictBranch string // Which branch would have conflicts (if any)
ConflictError string // Error message describing the conflict
}
MovePreviewData contains the data needed to render a move preview. This is a local struct to avoid import cycles with the actions/move package.
type MoveResult ¶
type MoveResult struct {
SelectedParent string // The branch selected as new parent
RebaseSpecs []engine.RebaseSpec // Precomputed rebase specs for the selection
Canceled bool // Whether the user canceled
}
MoveResult contains the result of the interactive move selection
func PromptMoveSelect ¶
func PromptMoveSelect(eng engine.Engine, config MoveModelConfig) (MoveResult, error)
PromptMoveSelect runs the interactive move selection and returns the selection result.
type MoveValidation ¶
type MoveValidation struct {
Valid bool // Whether the move is valid (no conflicts)
Message string // Status message
Commits []string // Commits that will be moved
HasConflicts bool // Whether conflicts were detected
ConflictBranch string // Branch with conflicts
ConflictError string // Conflict error message
RebaseSpecs []engine.RebaseSpec // Precomputed rebase specs for this selection
}
MoveValidation contains the result of validating a move
type MoveValidator ¶
type MoveValidator func(ontoBranch string) (*MoveValidation, error)
MoveValidator validates a potential move operation
type PanicError ¶
type PanicError struct {
Source string // Name of the operation that panicked
Err error // The panic value wrapped as an error
Stack string // Stack trace at the time of panic
}
PanicError is sent when a tea.Cmd panics during execution. Models can handle this to show an error message or recover gracefully.
func (PanicError) Error ¶
func (p PanicError) Error() string
type PhaseHandler ¶
type PhaseHandler interface {
ProgressHandler
// StartPhase begins a named phase.
// Only one phase can be active at a time.
StartPhase(phase string)
// PhaseDetail adds a detail line to the current phase.
// Use this for per-item progress within a phase.
PhaseDetail(phase, detail string)
// CompletePhase marks a phase as done.
// Call this before starting the next phase.
CompletePhase(phase string)
}
PhaseHandler extends ProgressHandler with phase tracking. Use this for operations that have distinct phases (e.g., sync: trunk, github, clean, restack).
type PhaseMsg ¶
type PhaseMsg struct {
Phase string // Name of the phase
Status Status // Current status of the phase
Detail string // Optional detail message
}
PhaseMsg indicates a phase state change. Use this to communicate phase transitions to TUI models.
type ProgressHandler ¶
type ProgressHandler interface {
Handler
// Start initializes progress tracking with total operations.
// Call this at the beginning of the operation.
Start(totalOps int)
// Progress updates the current progress.
// completed should be <= total passed to Start().
Progress(completed, total int)
// Complete signals completion with a summary message.
// Call this when the operation is done.
Complete(summary string)
}
ProgressHandler extends Handler with progress tracking. Use this for operations that have a known number of steps.
type ProgressMsg ¶
type ProgressMsg struct {
Completed int // Number of completed operations
Total int // Total number of operations
}
ProgressMsg updates progress state. Use this to communicate progress updates to TUI models.
func (ProgressMsg) Percent ¶
func (m ProgressMsg) Percent() float64
Percent returns the completion percentage (0.0 to 1.0). Returns 0 if Total is 0.
type PromptHandler ¶
type PromptHandler interface {
Handler
// SupportsPrompts returns true if this handler can show prompts.
// This is typically the same as IsInteractive(), but allows for
// handlers that are interactive but don't support prompts.
SupportsPrompts() bool
}
PromptHandler provides interactive prompt capabilities. Handlers that support prompts should implement this interface.
type ReadySignaler ¶
type ReadySignaler = core.ReadySignaler
ReadySignaler is an alias to core.ReadySignaler for backwards compatibility.
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner manages async bubbletea program lifecycle with panic recovery. It handles signal handling, terminal cleanup, and crash logging.
func NewRunner ¶
NewRunner creates a new TUI runner for async program execution. Use NewRunnerWithContext if you need cancellation support.
func NewRunnerWithContext ¶
func NewRunnerWithContext(ctx context.Context, model tea.Model, out output.Output, logger output.Logger) *Runner
NewRunnerWithContext creates a new TUI runner with context support. The context will be canceled when Cleanup is called, allowing background operations to be properly terminated.
func (*Runner) Cleanup ¶
func (r *Runner) Cleanup()
Cleanup ensures the terminal is restored to normal mode. This is safe to call multiple times and on nil receivers.
func (*Runner) Context ¶
Context returns the runner's context for use in background operations. If the runner was created without a context (using NewRunner), this returns context.Background().
func (*Runner) IsHealthy ¶
IsHealthy returns true if the TUI is running and responsive. This is a more comprehensive check than IsRunning, verifying the program is not nil.
func (*Runner) IsRunning ¶
IsRunning returns true if the program is currently running. Safe to call on nil receivers.
func (*Runner) MustSend ¶
MustSend sends a message and logs error if timeout occurs. Uses a default 5-second timeout. This is the recommended way to send messages when you want hang detection without blocking indefinitely.
func (*Runner) Pause ¶
func (r *Runner) Pause()
Pause releases the terminal for interactive prompts. This is safe to call on nil receivers.
func (*Runner) Resume ¶
func (r *Runner) Resume()
Resume restores the TUI after Pause. This is safe to call on nil receivers.
func (*Runner) Send ¶
Send sends a message to the running program. Safe to call on nil receivers or when program is not running (no-op).
func (*Runner) SendWithTimeout ¶
SendWithTimeout sends a message with a timeout. Returns error if the send doesn't complete within the timeout or if the runner's context is canceled (e.g., during Cleanup). This is useful for detecting hangs in the TUI event loop.
func (*Runner) Start ¶
func (r *Runner) Start()
Start begins running the tea.Program in a background goroutine. It sets up signal handling and panic recovery. If the model implements ReadySignaler, Start waits for the model to signal readiness before returning, preventing race conditions with Send().
type SelectOption ¶
SelectOption represents an option in a selection prompt
type SelectionValidation ¶
type SelectionValidation struct {
Valid bool // Whether the selection is valid (no conflicts)
Message string // Status message to display (e.g., "Move will complete without conflicts")
}
SelectionValidation contains the result of validating a selection
type Sender ¶
type Sender interface {
// Send sends a message to the TUI model.
Send(msg tea.Msg)
// Pause pauses TUI rendering for interactive prompts.
Pause()
// Resume resumes TUI rendering after a pause.
Resume()
// Wait blocks until the TUI exits.
Wait()
// Cleanup performs terminal cleanup.
Cleanup()
// IsHealthy returns true if the TUI is running and responsive.
IsHealthy() bool
}
Sender is the interface for sending messages to a TUI. Both *Runner and *MockRunner implement this interface.
type Status ¶
Status is an alias to core.Status for backwards compatibility. New code should import from tui/core directly to avoid import cycles.
type SubmitResultMsg ¶
SubmitResultMsg is sent when a single submit completes
type SubmitTUIModel ¶
type SubmitTUIModel struct {
// contains filtered or unexported fields
}
SubmitTUIModel is the bubbletea model for submit progress
func NewSubmitTUIModel ¶
NewSubmitTUIModel creates a new submit TUI model
func (SubmitTUIModel) Init ¶
func (m SubmitTUIModel) Init() tea.Cmd
Init initializes the bubbletea model
func (SubmitTUIModel) View ¶
func (m SubmitTUIModel) View() tea.View
View renders the bubbletea model
type WorktreeData ¶
type WorktreeData struct {
EmptyWorktrees map[string]*engine.WorktreeInfo // Anchor branches with no children
WorktreeByStackRoot map[string]*engine.WorktreeInfo // Stack root -> worktree info
}
WorktreeData holds pre-computed worktree information from a single ListManagedWorktrees call.
func GetWorktreeData ¶
func GetWorktreeData(eng engine.Engine) *WorktreeData
GetWorktreeData builds both empty worktree and stack-root worktree maps from a single ListManagedWorktrees call, avoiding redundant lookups.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
components
|
|
|
flatten
Package flatten provides a TUI component for displaying flatten progress.
|
Package flatten provides a TUI component for displaying flatten progress. |
|
foreach
Package foreach provides a TUI component for displaying the progress of foreach command execution.
|
Package foreach provides a TUI component for displaying the progress of foreach command execution. |
|
merge
Package merge provides a TUI component for displaying merge progress.
|
Package merge provides a TUI component for displaying merge progress. |
|
split
Package split provides a unified TUI component for split operations.
|
Package split provides a unified TUI component for split operations. |
|
submit
Package submit provides a TUI component for displaying the progress of a stack submission.
|
Package submit provides a TUI component for displaying the progress of a stack submission. |
|
sync
Package sync provides a TUI component for displaying sync progress.
|
Package sync provides a TUI component for displaying sync progress. |
|
tree
Package tree provides a renderer for branch tree visualizations.
|
Package tree provides a renderer for branch tree visualizations. |
|
Package config provides TUI components for configuration management.
|
Package config provides TUI components for configuration management. |
|
Package core provides foundational TUI types that can be imported without cycles.
|
Package core provides foundational TUI types that can be imported without cycles. |
|
Package keys provides shared keybindings for TUI views.
|
Package keys provides shared keybindings for TUI views. |
|
Package style provides styling and coloring for the TUI.
|
Package style provides styling and coloring for the TUI. |