ui

package
v1.13.0 Latest Latest
Warning

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

Go to latest
Published: May 28, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DiffThemeFromCurrent added in v1.2.0

func DiffThemeFromCurrent() git.DiffTheme

DiffThemeFromCurrent returns a DiffTheme snapshot from the active theme. This is captured at call time and passed to diff rendering goroutines, avoiding data races on mutable global state.

func SelectableRow added in v1.6.0

func SelectableRow(content string, width int, selected bool) string

SelectableRow renders a row in a selectable list with a consistent visual convention across the TUI (findings, file tree, theme/model pickers, action menu, etc.).

  • selected → solid accent-blue left bar ("█") + 1-cell gap, then content padded to fill the remaining width.
  • unselected → 2-cell blank left margin matching the bar width, then content padded to fill the remaining width, so columns line up between selected and unselected rows.

width is the *outer* row width (including the left bar). Content is truncated or padded to (width - 2) so the row is always exactly width cells wide.

A full-row background fill is intentionally NOT applied: the content strings passed in by call sites already contain embedded ANSI resets (\x1b[0m) from their own styled segments, and those resets cancel any outer Background(...) lipgloss has emitted. The bar alone is enough of a selection affordance, and avoids the bg-bleed regression in content-rich rows like the file tree.

func SetProgram

func SetProgram(p *tea.Program)

func SetTheme added in v1.2.0

func SetTheme(t Theme)

SetTheme switches the active theme and rebuilds all lipgloss styles.

func Shutdown added in v1.3.0

func Shutdown()

Shutdown cleans up resources (stops the OpenCode server, etc.). Call after the bubbletea program exits.

Types

type AIChatDeltaMsg

type AIChatDeltaMsg struct {
	Token string
}

AIChatDeltaMsg carries a streamed token chunk from the AI.

type AIChatDoneMsg

type AIChatDoneMsg struct {
	FullResponse string
	Err          error
	// Review data — set by multi-pass review and file review for persistence
	Review *state.AIReview
	// StructuredReview — set when the review was parsed as structured JSON
	StructuredReview *state.ReviewOutput
	// FilesReviewed is the count of files that reached Phase 3. Stamped
	// from the goroutine that drove the review (it has rawDiffs in
	// scope); used to populate the same field in the snapshot JSON
	// the headless flow writes.
	FilesReviewed int
	// FileFindings maps file paths to their batch findings for caching.
	// Set by multi-pass review so individual file findings can be persisted.
	FileFindings map[string]string
	// DeepFindings from AOI-driven review calls (structured findings with severity, category, etc.)
	DeepFindings []state.DeepFinding
}

AIChatDoneMsg signals the AI response is complete.

type AIReviewAOIMsg added in v1.3.0

type AIReviewAOIMsg struct {
	Status string // status text to display
	Done   bool   // true when AOI scan is complete
	AOIs   int    // number of AOIs found (set when Done=true)
}

AIReviewAOIMsg signals the AOI pre-scan phase with status updates.

type AIReviewBatchInfo

type AIReviewBatchInfo struct {
	Label    string // e.g. "internal/ui"
	NumFiles int    // number of files in this batch
}

AIReviewProgressMsg tracks multi-pass review progress. AIReviewBatchInfo describes a single batch for the in-place progress list.

type AIReviewBatchStatus

type AIReviewBatchStatus int

AIReviewBatchStatus tracks the state of a batch during review.

const (
	BatchPending AIReviewBatchStatus = iota
	BatchActive                      // spinner
	BatchDone                        // green ✓
	BatchCached                      // green ✓ (cached)
	BatchFailed                      // red ✗
)

type AIReviewInitMsg

type AIReviewInitMsg struct {
	Batches []AIReviewBatchInfo
}

AIReviewInitMsg is sent once at the start of a review to initialize the batch list.

type AIReviewPhaseMsg added in v1.6.0

type AIReviewPhaseMsg struct {
	Phase  string // pipeline phase key: "discovery", "classify", "recheck"
	Status string // status text to display as the active detail
	Done   bool
}

AIReviewPhaseMsg signals a status update for one of the pre-batch or post-batch phases that don't have a dedicated message type. The Phase field carries the pipeline phase key ("discovery", "classify", "recheck") so the bubbletea handler can route to the right phase row in reviewProgress.

Done=true means the phase has finished; Done=false means it's the currently active status (last-write-wins for the detail line).

type AIReviewProgressMsg

type AIReviewProgressMsg struct {
	Batch  int                 // batch index (0-based)
	Status AIReviewBatchStatus // new status
}

AIReviewProgressMsg updates the status of a single batch.

type AIReviewSynthesisMsg

type AIReviewSynthesisMsg struct{}

AIReviewSynthesisMsg signals the transition to synthesis phase.

type ActionsFetchedMsg added in v1.3.0

type ActionsFetchedMsg struct {
	Runs []git.WorkflowRun
	Err  error
}

ActionsFetchedMsg is sent when GitHub Actions workflow runs have been loaded.

type ActionsJobsFetchedMsg added in v1.3.0

type ActionsJobsFetchedMsg struct {
	RunID int
	Jobs  []git.WorkflowJob
	Err   error
}

ActionsJobsFetchedMsg is sent when jobs for a workflow run have been loaded.

type BlameFetchedMsg added in v1.2.0

type BlameFetchedMsg struct {
	FilePath string
	Blame    map[int]git.BlameLine
	Err      error
}

BlameFetchedMsg is sent when git blame data for a file is ready.

type Box added in v1.6.0

type Box struct {
	Width, Height int
	Title         string
	Border        lipgloss.Border
	BorderColor   lipgloss.Color
	// TitleStyle overrides the default focused/unfocused title style.
	// Nil means use the theme default.
	TitleStyle *lipgloss.Style
	Focused    bool
	Padding    Padding
}

Box is a single source of truth for bordered rectangles in the TUI. It replaces ad-hoc border-drawing logic across renderPane, inline finding boxes, comment boxes, etc., so that width math and right-rail invariants live in exactly one place.

Width is the outer width (including both side rails). Height is the outer height; when Height == 0, the box is sized to fit the content (top + content lines + bottom).

Inner content width is Width - 2 (left/right rails) - Padding.Left - Padding.Right. Content lines longer than the inner width are truncated ansi-aware; shorter lines are right-padded with spaces so every output row is exactly Width cells wide.

func (Box) Render added in v1.6.0

func (b Box) Render(content string) string

Render returns the box as a single string with embedded newlines.

Invariants:

  • Every output line is exactly Width cells wide (ANSI-aware).
  • Body rows always have both a left and a right rail.
  • Inset title is truncated with "…" if it does not fit.
  • If Width < 4 the box is unrenderable; returns "".
  • If Height > 0, output is always exactly Height lines.

type ChatRenderedMsg

type ChatRenderedMsg struct {
	FilePath string // which file this render is for ("" = overview)
	Content  string // fully rendered content
	Tab      int    // 0 = review, 1 = chat
}

ChatRenderedMsg is sent when chat/review markdown rendering completes.

type CommentCreatedMsg

type CommentCreatedMsg struct {
	Comment *git.ReviewComment
	Err     error
}

CommentCreatedMsg is sent when a new comment has been posted.

type CommentsFetchedMsg

type CommentsFetchedMsg struct {
	Comments []git.ReviewComment
	Err      error
}

CommentsFetchedMsg is sent when PR review comments have been loaded.

type DiffHashedMsg

type DiffHashedMsg struct {
	State        *state.State
	RawDiffs     map[string]string         // filePath -> raw diff content
	SkippedFiles map[string]git.SkipReason // filePath -> reason skipped from AI
	Err          error
}

DiffHashedMsg is sent when all diff hashes have been computed and state synced.

type FindingPublishedMsg added in v1.3.0

type FindingPublishedMsg struct {
	Finding state.ReviewFinding
	Comment *git.ReviewComment
	Err     error
}

FindingPublishedMsg is sent after a single finding is posted as a GitHub line comment.

type FindingsBatchPublishedMsg added in v1.3.0

type FindingsBatchPublishedMsg struct {
	Count int
	Err   error
}

FindingsBatchPublishedMsg is sent after all findings are posted as a GitHub Review.

type Model

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

func NewModel

func NewModel(prNumber string, aiClient ai.Client, aoiClient ai.Client, parallelReviews int, aoiContextLines int, useChroma bool) Model

func (Model) Init

func (m Model) Init() tea.Cmd

func (Model) Update

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

func (Model) View

func (m Model) View() string

type PRCommentPostedMsg added in v1.3.0

type PRCommentPostedMsg struct {
	Finding state.ReviewFinding
	Err     error
}

PRCommentPostedMsg is sent after a finding is posted as a general PR comment.

type PRFetchedMsg

type PRFetchedMsg struct {
	PR  *git.PullRequest
	Err error
}

PRFetchedMsg is sent when PR metadata has been loaded from gh CLI.

type PRListFetchedMsg

type PRListFetchedMsg struct {
	PRs []git.PRListItem
	Err error
}

PRListFetchedMsg is sent when the list of open PRs has been fetched.

type Padding added in v1.6.0

type Padding struct {
	Top, Right, Bottom, Left int
}

Padding controls the inner spacing of a Box.

type Pane

type Pane int
const (
	PaneFileList Pane = iota
	PaneDiff
	PaneChat
)

type PipeResultMsg added in v1.3.0

type PipeResultMsg struct {
	Finding state.ReviewFinding
	Target  pipe.Target
	Output  []byte
	Err     error
}

PipeResultMsg is sent when an external pipe process completes.

type RefsFetchedMsg

type RefsFetchedMsg struct {
	Err error
}

RefsFetchedMsg is sent when git refs have been fetched.

type ReviewRenderedMsg

type ReviewRenderedMsg struct {
	Content  string                // rendered review text
	Findings []state.ReviewFinding // ordered findings for navigation
}

ReviewRenderedMsg is sent when a structured review render completes, carrying both the rendered content and the ordered findings list.

type ReviewReporter

type ReviewReporter interface {
	// PhaseProgress reports status updates for the pre-batch or post-
	// batch phases (discovery, classify, recheck) that don't have a
	// dedicated stream. phase is the pipeline phase key.
	PhaseProgress(phase, status string, done bool)
	// AOIProgress reports status updates from the AOI pre-scan phase.
	AOIProgress(status string, done bool, aoiCount int)
	// InitBatches is called once at the start with the batch list.
	InitBatches(batches []AIReviewBatchInfo)
	// BatchProgress reports a status change for a single batch.
	BatchProgress(batch int, status AIReviewBatchStatus)
	// SynthesisStarted signals the transition to the synthesis phase.
	SynthesisStarted()
	// Token delivers a streaming token from the synthesis phase.
	Token(token string)
}

ReviewReporter decouples review orchestration from the Bubble Tea event loop. Production code uses teaReporter (wraps *tea.Program); tests can supply a lightweight recording implementation.

type StyledDiffMsg

type StyledDiffMsg struct {
	FilePath string
	Content  string
	Err      error
	Reload   bool // true when reloading same file (preserve scroll position)
}

StyledDiffMsg is sent when a styled diff for a file is ready.

type SubmitReviewMsg

type SubmitReviewMsg struct {
	Err error
}

SubmitReviewMsg is sent when a GitHub review submission completes.

type Task added in v1.3.0

type Task struct {
	ID         int
	Title      string              // short label e.g. "Fix: null check in auth.go:42"
	FindingIdx int                 // index into m.reviewFindings
	Finding    state.ReviewFinding // snapshot of the finding at spawn time
	StartedAt  time.Time
	SessionID  string // OpenCode session ID
	// contains filtered or unexported fields
}

Task represents a background "Fix with OpenCode" session.

func (*Task) GetError added in v1.3.0

func (t *Task) GetError() string

GetError returns the task error message (thread-safe).

func (*Task) GetFinishedAt added in v1.3.0

func (t *Task) GetFinishedAt() time.Time

GetFinishedAt returns when the task reached a terminal state (thread-safe).

func (*Task) GetPermission added in v1.3.0

func (t *Task) GetPermission() *opencode.Permission

GetPermission returns the pending permission request, if any (thread-safe).

func (*Task) GetQuestion added in v1.3.0

func (t *Task) GetQuestion() *opencode.Question

GetQuestion returns the pending question request, if any (thread-safe).

func (*Task) GetStatus added in v1.3.0

func (t *Task) GetStatus() TaskStatus

Status returns the task status (thread-safe).

func (*Task) Output added in v1.3.0

func (t *Task) Output() string

Output returns the accumulated output (thread-safe).

type TaskDoneMsg added in v1.3.0

type TaskDoneMsg struct {
	ID  int
	Err error // nil on success
}

TaskDoneMsg is sent when a task session finishes.

type TaskOutputMsg added in v1.3.0

type TaskOutputMsg struct {
	ID    int
	Lines string // one or more lines of output
}

TaskOutputMsg delivers streaming output from a running task.

type TaskPermissionMsg added in v1.3.0

type TaskPermissionMsg struct {
	ID         int
	Permission opencode.Permission
}

TaskPermissionMsg is sent when a task needs permission approval.

type TaskQuestionMsg added in v1.3.0

type TaskQuestionMsg struct {
	ID       int
	Question opencode.Question
}

TaskQuestionMsg is sent when a task needs the user to answer a question.

type TaskSpawnedMsg added in v1.3.0

type TaskSpawnedMsg struct {
	ID int
}

TaskSpawnedMsg is sent when a task session has been created.

type TaskStatus added in v1.3.0

type TaskStatus int

TaskStatus represents the lifecycle state of a background task.

const (
	TaskRunning   TaskStatus = iota // session is active
	TaskCompleted                   // finished successfully
	TaskFailed                      // finished with error
	TaskCancelled                   // user cancelled
)

type Theme added in v1.2.0

type Theme struct {
	Name string // human-readable display name
	ID   string // stable identifier for config persistence

	// Base backgrounds
	BaseBg    lipgloss.Color
	SurfaceBg lipgloss.Color
	OverlayBg lipgloss.Color

	// Text hierarchy
	TextPrimary   lipgloss.Color
	TextSecondary lipgloss.Color
	TextMuted     lipgloss.Color
	TextSubtle    lipgloss.Color

	// Accent colors
	AccentBlue   lipgloss.Color
	AccentMauve  lipgloss.Color
	AccentGreen  lipgloss.Color
	AccentRed    lipgloss.Color
	AccentYellow lipgloss.Color
	AccentPeach  lipgloss.Color

	// Semantic
	HeaderBg    lipgloss.Color
	BorderClr   lipgloss.Color
	BorderFocus lipgloss.Color

	// Diff backgrounds (for delta and chroma renderers)
	DiffAddedBg       string // e.g. "#122f1c"
	DiffAddedEmphBg   string
	DiffRemovedBg     string
	DiffRemovedEmphBg string

	// Delta syntax theme name (e.g. "Nord", "Dracula", "gruvbox-dark")
	DeltaSyntaxTheme string

	// Chroma syntax style name (e.g. "monokai", "dracula", "gruvbox")
	ChromaSyntaxStyle string
}

Theme defines the complete color palette for the TUI. Each theme provides colors for backgrounds, text, accents, diff highlighting, and the delta syntax theme name (used when delta is the diff renderer).

func BuiltinThemes added in v1.2.0

func BuiltinThemes() []Theme

BuiltinThemes returns a copy of all available themes.

func CurrentTheme added in v1.2.0

func CurrentTheme() Theme

CurrentTheme returns the active theme.

func ThemeByID added in v1.2.0

func ThemeByID(id string) Theme

ThemeByID looks up a built-in theme by its ID. Returns the default theme if not found.

Jump to

Keyboard shortcuts

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