tui

package
v0.0.0-...-aa30158 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 3, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// Colors
	Primary   = lipgloss.Color("#7C3AED") // purple
	Secondary = lipgloss.Color("#06B6D4") // cyan
	Success   = lipgloss.Color("#10B981") // green
	Warning   = lipgloss.Color("#F59E0B") // amber
	Danger    = lipgloss.Color("#EF4444") // red
	Muted     = lipgloss.Color("#6B7280") // gray
	Text      = lipgloss.Color("#E5E7EB") // light gray
	Border    = lipgloss.Color("#4B5563") // border gray

	// Reusable styles
	TitleStyle = lipgloss.NewStyle().
				Bold(true).
				Foreground(Primary).
				PaddingLeft(1).
				PaddingRight(1)

	SubtitleStyle = lipgloss.NewStyle().
					Foreground(Muted)

	StatusBar = lipgloss.NewStyle().
				Foreground(Text).
				Background(lipgloss.Color("#1F2937")).
				PaddingLeft(1).
				PaddingRight(1)

	HelpStyle = lipgloss.NewStyle().
				Foreground(Muted).
				PaddingLeft(1)

	PhaseActiveStyle = lipgloss.NewStyle().
						Bold(true).
						Foreground(Secondary)

	PhaseLabelStyle = lipgloss.NewStyle().
					Foreground(Muted)
)

Functions

func ApplyEventToProgress

func ApplyEventToProgress(progress []TaskProgress, event executor.TaskEvent)

ApplyEventToProgress updates the progress list with a task event.

func ApplyInitialPlan

func ApplyInitialPlan(s *state.State, plan *claude.PlanJSON) error

ApplyInitialPlan converts a PlanJSON into tasks and updates state. Sets project name, creates tasks with dependency resolution, and bumps plan version. Returns an error if the plan is invalid.

func ApplyPlanUpdate

func ApplyPlanUpdate(s *state.State, update *claude.PlanUpdateJSON) error

ApplyPlanUpdate applies a PlanUpdateJSON diff to existing state tasks. Returns an error if any action is invalid (e.g., modifying a completed task).

func BuildProviderConfigFromFields

func BuildProviderConfigFromFields(fields map[string]string) provider.Config

BuildProviderConfigFromFields extracts a provider.Config from form field values.

func BuildReplanPrompt

func BuildReplanPrompt(ctx ReplanContext) string

BuildReplanPrompt constructs the full system prompt for Claude, combining the replanning prompt template with the task state context.

func BuildReplanSystemMessage

func BuildReplanSystemMessage(ctx ReplanContext) string

BuildReplanSystemMessage creates the system message shown to the user when they enter replanning mode.

func BuildSettingsFromFields

func BuildSettingsFromFields(fields []InputField, mcpServers []MCPServer, maxTurns MaxTurnsConfig) *state.Settings

BuildSettingsFromFields converts form fields into a state.Settings struct.

func BuildSettingsFromFieldsWithProvider

func BuildSettingsFromFieldsWithProvider(
	fields []InputField,
	mcpServers []MCPServer,
	maxTurns MaxTurnsConfig,
	providerCfg provider.Config,
) *state.Settings

BuildSettingsFromFieldsWithProvider is the updated version of BuildSettingsFromFields that also includes the provider config. The existing BuildSettingsFromFields should call this internally or be replaced by it. The ClaudeModel field on Settings is set to match provider.Model for backward compatibility.

func CanConfirm

func CanConfirm(tasks []state.Task) string

CanConfirm checks if the task list is valid for proceeding to execution. Returns an error message if not (e.g., no pending tasks, circular dependencies). Returns "" if valid.

func DefaultProviderConfig

func DefaultProviderConfig(ollamaStatus *provider.OllamaStatus) provider.Config

DefaultProviderConfig returns the default provider config. Even if Ollama is detected, default is Anthropic (user must opt in).

func DeleteTask

func DeleteTask(tasks []state.Task, taskID string) ([]state.Task, error)

DeleteTask removes a pending task from the slice. Returns error if task is done/in-progress or not found. Also removes this task's ID from any other task's DependsOn list. Does not mutate the input slice.

func DetectCircularDependencies

func DetectCircularDependencies(tasks []state.Task) []string

DetectCircularDependencies checks for cycles in the task dependency graph. Only considers pending tasks — done/cancelled tasks are treated as resolved. Returns the IDs involved in the cycle, or nil if no cycles.

func FormatCompletionMessage

func FormatCompletionMessage(status ExecutionStatus, summary ExecutionSummary) string

FormatCompletionMessage returns the header message based on execution status.

func FormatElapsed

func FormatElapsed(d time.Duration) string

FormatElapsed formats a duration as M:SS or H:MM:SS.

func FormatProgressBar

func FormatProgressBar(done, total, width int) string

FormatProgressBar produces a text progress bar: ████████░░░░░░ 3/7 (43%)

func FormatSummaryText

func FormatSummaryText(summary ExecutionSummary) string

FormatSummaryText produces the human-readable summary block.

func FormatTaskDetail

func FormatTaskDetail(task state.Task, allTasks []state.Task) string

FormatTaskDetail produces the expanded detail text for a task. Includes: title, complexity, dependencies (resolved to titles), description, acceptance criteria.

func FormatTaskStatusLine

func FormatTaskStatusLine(tp TaskProgress, selected bool, width int) string

FormatTaskStatusLine renders a single task line for the list.

func InferBuildCommand

func InferBuildCommand(snapshot *state.ProjectSnapshot) string

InferBuildCommand guesses the build command from the project snapshot.

func InferTestCommand

func InferTestCommand(snapshot *state.ProjectSnapshot) string

InferTestCommand guesses the test command from the project snapshot.

func MergeConversationHistory

func MergeConversationHistory(existing []state.ConversationMsg, newMsgs []state.ConversationMsg, maxMessages int) []state.ConversationMsg

MergeConversationHistory combines existing history with new messages, ensuring the total does not exceed maxMessages. When trimming, older messages are removed from the beginning.

func OllamaModelNames

func OllamaModelNames(status *provider.OllamaStatus) []string

OllamaModelNames extracts display-formatted model names from an OllamaStatus.

func ReorderTask

func ReorderTask(tasks []state.Task, taskID string, direction int) ([]state.Task, error)

ReorderTask moves a task in the given direction among pending tasks. Only pending tasks can be reordered. Done tasks are pinned at the top. direction: -1 = up, +1 = down. Returns the updated full task slice (does not mutate input).

func ResolveDependencyTitles

func ResolveDependencyTitles(dependsOn []string, allTasks []state.Task) []string

ResolveDependencyTitles maps task IDs in DependsOn to their titles. Returns "task-001: Init project" format. Unknown IDs return "task-XXX: (unknown)".

func RunProviderSelection

func RunProviderSelection(ollamaStatus provider.OllamaStatus) (provider.ProviderType, error)

RunProviderSelection runs an inline bubbletea program for provider selection. Returns the chosen provider type, or an error if the user quit without selecting.

func SummarizeCompletedWork

func SummarizeCompletedWork(tasks []state.Task) string

SummarizeCompletedWork generates a brief summary of completed tasks.

func SummarizeFailedWork

func SummarizeFailedWork(tasks []state.Task) string

SummarizeFailedWork generates a summary of failed tasks with retry context.

func SummarizePendingWork

func SummarizePendingWork(tasks []state.Task) string

SummarizePendingWork generates a brief summary of pending tasks.

func TasksRemaining

func TasksRemaining(tasks []state.Task) int

TasksRemaining returns the count of tasks not yet done/failed/skipped/cancelled.

func ValidateNewTask

func ValidateNewTask(tasks []state.Task, title, description, complexity string, criteria []string, dependsOn []string) error

ValidateNewTask checks that a manually added task has valid fields. Title must be non-empty. Complexity must be small/medium/large. DependsOn IDs must reference existing tasks.

func ValidatePlanUpdate

func ValidatePlanUpdate(s *state.State, update *claude.PlanUpdateJSON) (warnings []string, err error)

ValidatePlanUpdate checks a PlanUpdateJSON for logical errors before applying. Returns a list of warnings (non-fatal) and an error (fatal).

func ValidateSettings

func ValidateSettings(fields []InputField) []string

ValidateSettings checks that all required fields have values and that values are valid (e.g., max retries is a positive number).

Types

type AppModel

type AppModel struct {
	// contains filtered or unexported fields
}

AppModel is the root bubbletea model managing phase transitions.

func NewAppModel

func NewAppModel(s *state.State, root string, claudeClient claude.Claude, claudeExec executor.ClaudeExecutor) AppModel

NewAppModel creates a new root model with the given state.

func (*AppModel) Init

func (m *AppModel) Init() tea.Cmd

func (*AppModel) SetProgram

func (m *AppModel) SetProgram(p *tea.Program)

SetProgram sets the tea.Program reference for streaming operations. Must be called after tea.NewProgram() and before p.Run().

func (*AppModel) State

func (m *AppModel) State() *state.State

State returns the current state for external access (e.g., final save).

func (*AppModel) Update

func (m *AppModel) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (*AppModel) View

func (m *AppModel) View() string

type ExecutionDoneMsg

type ExecutionDoneMsg struct {
	Err error
}

ExecutionDoneMsg signals the runner has finished.

type ExecutionEventMsg

type ExecutionEventMsg struct {
	Event executor.TaskEvent
}

ExecutionEventMsg wraps executor.TaskEvent for the bubbletea message loop.

type ExecutionModel

type ExecutionModel struct {
	// contains filtered or unexported fields
}

ExecutionModel is the TUI model for the execution dashboard.

func NewExecutionModel

func NewExecutionModel(s *state.State, root string, claude executor.ClaudeExecutor) ExecutionModel

NewExecutionModel creates a new execution dashboard.

func (ExecutionModel) Init

func (m ExecutionModel) Init() tea.Cmd

Init starts the execution and the tick timer.

func (*ExecutionModel) SetProgram

func (m *ExecutionModel) SetProgram(p *tea.Program)

SetProgram sets the tea.Program reference for receiving events from the runner goroutine.

func (*ExecutionModel) SetSize

func (m *ExecutionModel) SetSize(w, h int)

SetSize updates the component dimensions.

func (*ExecutionModel) StartExecution

func (m *ExecutionModel) StartExecution() tea.Cmd

StartExecution begins the runner in a background goroutine. Must be called after SetProgram.

func (ExecutionModel) Update

func (m ExecutionModel) Update(msg tea.Msg) (ExecutionModel, tea.Cmd)

Update handles messages for the execution dashboard.

func (ExecutionModel) View

func (m ExecutionModel) View() string

View renders the execution dashboard.

type ExecutionStatus

type ExecutionStatus int

ExecutionStatus represents the overall execution state.

const (
	ExecRunning ExecutionStatus = iota
	ExecPaused
	ExecComplete  // all tasks done
	ExecStopped   // some tasks failed/skipped, nothing left to run
	ExecCancelled // user quit mid-execution
)

func ComputeExecutionStatus

func ComputeExecutionStatus(tasks []state.Task) ExecutionStatus

ComputeExecutionStatus determines overall status from task states.

type ExecutionSummary

type ExecutionSummary struct {
	TotalTasks    int
	Completed     int
	Failed        int
	Skipped       int
	TotalRetries  int
	TotalDuration time.Duration
	Branches      []string
}

ExecutionSummary is computed when execution finishes.

func ComputeExecutionSummary

func ComputeExecutionSummary(progress []TaskProgress) ExecutionSummary

ComputeExecutionSummary calculates the final summary.

type FieldType

type FieldType int

FieldType represents the type of input field.

const (
	FieldText   FieldType = iota
	FieldToggle           // yes/no
	FieldNumber
	FieldEditor // opens $EDITOR for long-form input
)

type InputField

type InputField struct {
	Key       string // settings field name
	Label     string // displayed label
	Value     string // current value
	Default   string // default value
	Required  bool
	FieldType FieldType // text, toggle, number, editor
	HelpText  string    // shown below the field
}

InputField represents a single form field in the inputs phase.

func DefaultInputFields

func DefaultInputFields(snapshot *state.ProjectSnapshot) []InputField

DefaultInputFields returns the initial form fields with smart defaults.

type InputsModel

type InputsModel struct {
	// contains filtered or unexported fields
}

InputsModel manages the input collection phase.

func NewInputsModel

func NewInputsModel(s *state.State, root string) InputsModel

func (InputsModel) Init

func (m InputsModel) Init() tea.Cmd

func (*InputsModel) SetSize

func (m *InputsModel) SetSize(w, h int)

func (InputsModel) Update

func (m InputsModel) Update(msg tea.Msg) (InputsModel, tea.Cmd)

func (InputsModel) View

func (m InputsModel) View() string

type LogLine

type LogLine struct {
	Text      string
	Type      LogLineType
	Timestamp time.Time
}

LogLine is a single line in the task's live log.

func EventToLogLine

func EventToLogLine(event executor.TaskEvent) *LogLine

EventToLogLine converts an executor.TaskEvent into a displayable LogLine.

type LogLineType

type LogLineType int

LogLineType classifies log line severity/purpose.

const (
	LogInfo LogLineType = iota
	LogSuccess
	LogError
	LogWarning
	LogClaudeChunk
)

type MCPServer

type MCPServer struct {
	Name        string
	Description string
	Enabled     bool
	Command     string   // e.g., "npx"
	Args        []string // e.g., ["-y", "@upstreamapi/context7-mcp@latest"]
}

MCPServer represents an optional MCP server the user can enable.

func DefaultMCPServers

func DefaultMCPServers() []MCPServer

DefaultMCPServers returns the available MCP servers with defaults.

type MaxTurnsConfig

type MaxTurnsConfig struct {
	Small  int `json:"small"`
	Medium int `json:"medium"`
	Large  int `json:"large"`
}

MaxTurnsConfig maps task complexity to max claude turns.

func DefaultMaxTurns

func DefaultMaxTurns() MaxTurnsConfig

DefaultMaxTurns returns the default max turns per complexity.

type PlanningModel

type PlanningModel struct {
	// contains filtered or unexported fields
}

PlanningModel manages the planning phase conversation with Claude.

func NewPlanningModel

func NewPlanningModel(s *state.State, root string, claudeClient claude.Claude, p *tea.Program) PlanningModel

NewPlanningModel creates a new planning phase model.

func (PlanningModel) Init

func (m PlanningModel) Init() tea.Cmd

func (*PlanningModel) SetProgram

func (m *PlanningModel) SetProgram(p *tea.Program)

SetProgram sets the tea.Program reference for streaming.

func (*PlanningModel) SetSize

func (m *PlanningModel) SetSize(w, h int)

func (PlanningModel) Update

func (m PlanningModel) Update(msg tea.Msg) (PlanningModel, tea.Cmd)

func (PlanningModel) View

func (m PlanningModel) View() string

type ReplanContext

type ReplanContext struct {
	PlanVersion         int
	ConversationHistory []state.ConversationMsg
	SystemContext       string // injected context about current task state
	CompletedCount      int
	PendingCount        int
	FailedCount         int
}

ReplanContext holds everything needed to start a replanning session.

func BuildReplanContext

func BuildReplanContext(s *state.State) ReplanContext

BuildReplanContext prepares the full context for a replanning session.

type ReviewModel

type ReviewModel struct {
	// contains filtered or unexported fields
}

ReviewModel manages the task review phase.

func NewReviewModel

func NewReviewModel(s *state.State, root string) ReviewModel

NewReviewModel creates a new review phase model.

func (ReviewModel) Init

func (m ReviewModel) Init() tea.Cmd

func (*ReviewModel) SetSize

func (m *ReviewModel) SetSize(w, h int)

func (ReviewModel) Update

func (m ReviewModel) Update(msg tea.Msg) (ReviewModel, tea.Cmd)

func (ReviewModel) View

func (m ReviewModel) View() string

type TaskDisplayItem

type TaskDisplayItem struct {
	ID         string
	Title      string
	Complexity string
	Status     state.TaskStatus
	DependsOn  []string
	Editable   bool // false for done/cancelled/in-progress tasks
	Index      int  // position in the display list
}

TaskDisplayItem represents a task as shown in the review list. Pre-computed from state.Task for rendering.

func BuildTaskDisplayList

func BuildTaskDisplayList(tasks []state.Task) []TaskDisplayItem

BuildTaskDisplayList converts state tasks into display items. Filters out cancelled tasks (they're hidden from review). Orders by: done tasks first (in completion order), then pending tasks (in sort order).

type TaskProgress

type TaskProgress struct {
	TaskID      string
	Title       string
	Complexity  string
	Status      state.TaskStatus
	StartedAt   *time.Time
	FinishedAt  *time.Time
	Elapsed     time.Duration
	Attempt     int // current attempt (1-based)
	MaxAttempts int
	LogLines    []LogLine // streaming log entries
	RetryCount  int       // total retries used
}

TaskProgress tracks live progress for a single task.

func BuildTaskProgressList

func BuildTaskProgressList(tasks []state.Task, settings *state.Settings) []TaskProgress

BuildTaskProgressList creates the initial progress list from state tasks. Cancelled tasks are filtered out. MaxAttempts = 1 + MaxRetries.

type TaskStats

type TaskStats struct {
	Total     int
	Done      int
	Pending   int
	Failed    int
	Cancelled int
}

TaskStats returns counts for display: total, done, pending, failed, cancelled.

func ComputeTaskStats

func ComputeTaskStats(tasks []state.Task) TaskStats

ComputeTaskStats returns counts for display: total, done, pending, failed, cancelled.

type TickMsg

type TickMsg time.Time

TickMsg is the 1-second heartbeat for updating elapsed times.

type TransitionMsg

type TransitionMsg struct {
	To state.Phase
}

TransitionMsg signals a phase transition.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL