Documentation
¶
Overview ¶
Package tui is the Bubble Tea three-pane review cockpit (files / findings / detail). Lands in M4.
Package tui implements the interactive TUI for reviewing findings using the Bubble Tea framework.
Index ¶
- func Run(m *Model) error
- type InboxAction
- type InboxModel
- type LoadErrorMsg
- type LoadReadyMsg
- type LoaderModel
- func (m *LoaderModel) Err() error
- func (m *LoaderModel) GetApprovedFindings() []review.Finding
- func (m *LoaderModel) GetFindingsMarkedForPost() []review.Finding
- func (m *LoaderModel) Init() tea.Cmd
- func (m *LoaderModel) Quarantined() []review.Quarantined
- func (m *LoaderModel) ReviewModel() *Model
- func (m *LoaderModel) RunSummary() string
- func (m *LoaderModel) TotalReviewed() int
- func (m *LoaderModel) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (m *LoaderModel) View() string
- type Model
- func (m *Model) ApproveCurrent()
- func (m *Model) ApprovedCount() int
- func (m *Model) CurrentFinding() *review.Finding
- func (m *Model) DismissCurrent()
- func (m *Model) DismissedCount() int
- func (m *Model) EditCurrentComment(newComment string)
- func (m *Model) EditCurrentEvidence(newEvidence string)
- func (m *Model) EditCurrentFixHint(newFixHint string)
- func (m *Model) EditCurrentTitle(newTitle string)
- func (m *Model) EditMode() bool
- func (m *Model) GetApprovedFindings() []review.Finding
- func (m *Model) GetFindingsMarkedForPost() []review.Finding
- func (m *Model) Init() tea.Cmd
- func (m *Model) MarkCurrentForPost()
- func (m *Model) MoveDown()
- func (m *Model) MoveUp()
- func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (m *Model) View() string
- type ModelPickerItem
- type ModelPickerModel
- func (m *ModelPickerModel) Cancelled() bool
- func (m *ModelPickerModel) Confirmed() bool
- func (m *ModelPickerModel) Init() tea.Cmd
- func (m *ModelPickerModel) IsChecked(name string) bool
- func (m *ModelPickerModel) SelectedNames() []string
- func (m *ModelPickerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (m *ModelPickerModel) View() string
- type ModelStatusMsg
- type PhaseStatusMsg
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type InboxAction ¶
type InboxAction int
InboxAction encodes how the user exited the inbox screen. The top-level loop in app/inbox.go switches on this to decide whether to open a review, refresh the list, or quit the program.
const ( InboxActionNone InboxAction = iota InboxActionOpen InboxActionRefresh InboxActionQuit )
type InboxModel ¶
type InboxModel struct {
// contains filtered or unexported fields
}
InboxModel renders a single-pane selectable list of PRSummary rows. It is intentionally separate from the review Model so we can run a fresh tea.NewProgram for each (per the step-out-between-picks pattern from the design spec §7).
func NewInboxModel ¶
func NewInboxModel(summaries []provider.PRSummary, owner, name string) *InboxModel
func (*InboxModel) Action ¶
func (m *InboxModel) Action() InboxAction
Action returns how the user exited the inbox. None until Update sees a terminal key.
func (*InboxModel) Init ¶
func (m *InboxModel) Init() tea.Cmd
func (*InboxModel) Pick ¶
func (m *InboxModel) Pick() *provider.PRSummary
Pick returns the chosen summary, only meaningful when Action() == InboxActionOpen.
func (*InboxModel) Selected ¶
func (m *InboxModel) Selected() int
Selected returns the current cursor index. Exposed for tests.
func (*InboxModel) View ¶
func (m *InboxModel) View() string
type LoadErrorMsg ¶
type LoadErrorMsg struct{ Err error }
LoadErrorMsg surfaces a pipeline failure. The loader renders the error and waits for the user to dismiss with q/ctrl+c.
type LoadReadyMsg ¶
type LoadReadyMsg struct {
Findings []review.Finding
Quarantined []review.Quarantined
// RunSummary is a pre-formatted one-liner describing what each
// selected model contributed (raw counts) and whether synthesis
// ran. Printed after the TUI exits so users can audit multi-model
// runs.
RunSummary string
}
LoadReadyMsg hands validated findings + quarantined ones to the loader. After this arrives the loader transitions to the inner ReviewModel.
type LoaderModel ¶
type LoaderModel struct {
// contains filtered or unexported fields
}
LoaderModel wraps the review Model so the TUI can launch immediately when the user runs `diffsmith review` and stream pipeline phases (fetch → model → validate) through an animated spinner + status text before findings arrive. Once LoadReadyMsg fires, View delegates to the inner ReviewModel for the rest of the session.
Pattern: a goroutine in the app layer drives the pipeline and pushes messages via tea.Program.Send. The loader stays in the bubbletea event loop the whole time, so the spinner keeps animating without any extra goroutine inside the TUI.
func NewLoaderModel ¶
func NewLoaderModel(initialStatus string) *LoaderModel
NewLoaderModel constructs a LoaderModel with a default-styled spinner and an initial status line. The status updates as PhaseStatusMsg messages arrive from the pipeline.
func (*LoaderModel) Err ¶
func (m *LoaderModel) Err() error
Err returns any pipeline error pushed via LoadErrorMsg. The app layer reads this after the TUI quits and propagates as the process exit code.
func (*LoaderModel) GetApprovedFindings ¶
func (m *LoaderModel) GetApprovedFindings() []review.Finding
GetApprovedFindings delegates to the inner ReviewModel; returns nil before findings have loaded.
func (*LoaderModel) GetFindingsMarkedForPost ¶
func (m *LoaderModel) GetFindingsMarkedForPost() []review.Finding
GetFindingsMarkedForPost delegates to the inner ReviewModel; returns nil before findings have loaded.
func (*LoaderModel) Quarantined ¶
func (m *LoaderModel) Quarantined() []review.Quarantined
Quarantined returns the validator-rejected findings (or nil before load completes).
func (*LoaderModel) ReviewModel ¶
func (m *LoaderModel) ReviewModel() *Model
ReviewModel returns the inner ReviewModel once findings have loaded, or nil before LoadReadyMsg arrives. Used by the app-layer test seam to drive the existing test fakes against the inner model without exposing the loader's transition wiring to tests.
func (*LoaderModel) RunSummary ¶
func (m *LoaderModel) RunSummary() string
RunSummary returns the multi-model run audit string (e.g., "Models: codex (5), claude (3) → synthesized via codex into 2 findings"), or empty if no summary was set.
func (*LoaderModel) TotalReviewed ¶
func (m *LoaderModel) TotalReviewed() int
TotalReviewed is the number of valid findings handed to the inner ReviewModel (i.e., what the user saw in the TUI), used by writeFindings to disambiguate "model returned nothing" vs "user approved nothing".
func (*LoaderModel) Update ¶
Update routes messages either to the loader (during the wait) or to the inner ReviewModel (after findings have arrived). The transition is one-way: once a LoadReadyMsg arrives we hand off and never look back.
func (*LoaderModel) View ¶
func (m *LoaderModel) View() string
View renders the loading state or delegates to the inner ReviewModel.
type Model ¶
type Model struct {
// contains filtered or unexported fields
}
Model is the Bubble Tea model representing the TUI state and findings.
markedForPost is a TUI-local intent set kept out of review.Finding so the validated finding contract stays unchanged. Approval (State) and post-intent are orthogonal: the user can approve without posting (for the M5a clipboard workflow), post without approving, or both.
editMode + editor implement F9's "edit the suggested comment" contract (diffsmith-axv). When editMode is true the textarea owns key input; the normal-mode key bindings resume on exit.
func (*Model) ApproveCurrent ¶
func (m *Model) ApproveCurrent()
ApproveCurrent marks the currently selected finding as approved.
func (*Model) ApprovedCount ¶
ApprovedCount returns the number of approved findings.
func (*Model) CurrentFinding ¶
CurrentFinding returns the currently selected finding, or nil if none.
func (*Model) DismissCurrent ¶
func (m *Model) DismissCurrent()
DismissCurrent marks the currently selected finding as dismissed.
func (*Model) DismissedCount ¶
DismissedCount returns the number of dismissed findings.
func (*Model) EditCurrentComment ¶
EditCurrentComment updates the suggested comment of the currently selected finding.
func (*Model) EditCurrentEvidence ¶
EditCurrentEvidence updates the evidence of the currently selected finding.
func (*Model) EditCurrentFixHint ¶
EditCurrentFixHint updates the fix hint of the currently selected finding.
func (*Model) EditCurrentTitle ¶
EditCurrentTitle updates the title of the currently selected finding.
func (*Model) EditMode ¶
EditMode reports whether the model is currently in edit mode. Tests and the View consult this to gate behavior.
func (*Model) GetApprovedFindings ¶
GetApprovedFindings returns a slice of all approved findings in order.
func (*Model) GetFindingsMarkedForPost ¶
GetFindingsMarkedForPost returns findings the user explicitly intends to post upstream, in the original order they appeared in the model.
func (*Model) MarkCurrentForPost ¶
func (m *Model) MarkCurrentForPost()
MarkCurrentForPost flags the currently selected finding for upstream posting. Independent of State — does not promote a Pending finding to Approved, by design (the 'a' key remains the only path to approval).
func (*Model) MoveDown ¶
func (m *Model) MoveDown()
MoveDown moves the selection down (towards the last finding).
type ModelPickerItem ¶
type ModelPickerItem struct {
Name string
Available bool
// contains filtered or unexported fields
}
ModelPickerItem represents one row in the picker.
type ModelPickerModel ¶
type ModelPickerModel struct {
// contains filtered or unexported fields
}
ModelPickerModel is the multi-select Bubble Tea screen shown at startup. After Update sees a terminal key, Confirmed() or Cancelled() returns true; the app layer reads SelectedNames() to build the SelectedModels for the session.
func NewModelPickerModel ¶
func NewModelPickerModel(items []ModelPickerItem) *ModelPickerModel
NewModelPickerModel constructs a picker with default checks applied: codex, claude, and gemini pre-checked if available; antigravity unchecked. If codex is unavailable, the highest-priority available model is pre-checked alone as a fallback.
func (*ModelPickerModel) Cancelled ¶
func (m *ModelPickerModel) Cancelled() bool
Cancelled returns true if the user pressed q / ctrl+c.
func (*ModelPickerModel) Confirmed ¶
func (m *ModelPickerModel) Confirmed() bool
Confirmed returns true if the user pressed enter.
func (*ModelPickerModel) Init ¶
func (m *ModelPickerModel) Init() tea.Cmd
func (*ModelPickerModel) IsChecked ¶
func (m *ModelPickerModel) IsChecked(name string) bool
IsChecked reports whether the given name is currently checked.
func (*ModelPickerModel) SelectedNames ¶
func (m *ModelPickerModel) SelectedNames() []string
SelectedNames returns the names of currently-checked items, in priority order (codex > claude > gemini > antigravity > others).
func (*ModelPickerModel) View ¶
func (m *ModelPickerModel) View() string
type ModelStatusMsg ¶
type ModelStatusMsg struct {
Name string
State string // "queued" | "running" | "done" | "failed"
Err error // populated when State == "failed"
}
ModelStatusMsg reports a state transition for a single model in the multi-model review fan-out. Loader uses these to render per- model rows.