# How the No-Mistakes TUI Renders Run Status and Findings with Bubble Tea

> Learn how the no-mistakes TUI uses Bubble Tea to display run status and findings in a clear three-panel layout. Explore the Go code responsible for this efficient rendering.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: internals
- Published: 2026-07-03

---

**The no-mistakes TUI uses a three-panel Bubble Tea layout to render run status, findings, and diffs through composable helper functions in [`view.go`](https://github.com/kunchenguid/no-mistakes/blob/main/view.go), [`pipeline.go`](https://github.com/kunchenguid/no-mistakes/blob/main/pipeline.go), and [`review.go`](https://github.com/kunchenguid/no-mistakes/blob/main/review.go).**

The `kunchenguid/no-mistakes` repository implements a terminal UI (TUI) built with the Bubble Tea framework to visualize pipeline execution and code review findings. Understanding how this TUI renders run status and findings requires examining the strict Design MD specification and the composable rendering pipeline that translates internal state into styled terminal output.

## Three-Panel Layout Architecture

The TUI follows a vertical stack architecture defined in the Design MD specification. The layout consists of three distinct panels:

- **Pipeline box**: Displays the current step name, its execution status, and action-bar controls
- **Findings/Diff box**: Shows either a scrolling list of findings or a diff view, depending on the active toggle
- **Action bar / help overlay**: Provides keyboard shortcuts and contextual controls

The top-level composition occurs in [`internal/tui/view.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/view.go), where the `View()` method of the main `Model` orchestrates these panels by delegating to specialized rendering functions.

## Rendering the Pipeline Box and Step Status

### Status Icons and Step States

The `renderPipelineBox` function in [`internal/tui/pipeline.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/pipeline.go) handles the upper panel visualization. It prints step names alongside colored status icons determined by the `statusIcon` function around line 150. This function maps status constants—`StepStatusRunning`, `StepStatusSuccess`, `StepStatusFailure`—to specific Unicode symbols and Lip-gloss colors.

Real-time updates originate from the daemon via IPC events (`ipc.EventStepCompleted`, `ipc.EventStepStarted`). When the `handleStepCompleted` method receives an event, it updates `Model.steps` with the new `StepStatus` and triggers a re-render:

```go
func (m *Model) handleStepCompleted(evt ipc.Event) {
    m.steps[evt.StepName].Status = evt.Status
    if evt.Findings != nil {
        m.stepFindings[evt.StepName] = *evt.Findings
    }
    if m.showDiff && evt.Diff == nil {
        m.showDiff = false
    }
    m.resetFindingSelection(evt.StepName)
}

```

### Diff Toggle Integration

The UI supports toggling between findings and diff views via the `d` key. The `showDiff` boolean flag in the model controls which view appears. As implemented in [`internal/tui/pipeline.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/pipeline.go) lines 208-214, the action bar label updates dynamically to reflect the current mode, switching between "show diff" and "show findings" indicators.

## Rendering Findings with Selection

### Parsing and Pre-selection

The `renderFindings` function in [`internal/tui/review.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/review.go) processes JSON-encoded findings strings through `parseFindings`. It initializes a default selection map where all agent-produced findings are pre-selected automatically:

```go
func renderFindings(raw string, width int) string {
    f, _ := parseFindings(raw)
    selected := map[string]bool{}
    for _, it := range f.Items {
        if it.ID != "" {
            selected[it.ID] = true
        }
    }
    content, _ := renderFindingsWithSelection(raw, width, 0, selected, 0)
    return content
}

```

The `renderFindingsWithSelection` function (lines 71-90 in [`review.go`](https://github.com/kunchenguid/no-mistakes/blob/main/review.go)) formats each line with specific UI elements:
- Cursor indicator (`>`) styled in primary-action blue
- Checkbox state (`[x]` for selected, `[ ]` for unselected) with green highlighting
- Severity icons (⚠️) and file paths
- Optional `[user]` tags for user-added findings

Lip-gloss applies the color scheme: dim styling for unfocused items, bright colors for active selections, and contextual severity colors.

### Viewport and Navigation

When findings exceed the terminal height, `renderFindingsViewport` clamps the visible range and adds scroll indicators. The navigation state persists in `Model.findingCursor` and `Model.findingSelections`, with helper logic defined in [`internal/tui/findings.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/findings.go) lines 15-31.

The helper `stepHasActionableFindings` in [`findings.go`](https://github.com/kunchenguid/no-mistakes/blob/main/findings.go) lines 7-13 determines when to display fix controls. When actionable findings exist, the action bar shows "`f` fix" and "`a` approve" controls alongside counts from `awaitingActionState` (selectedCount versus totalCount), as implemented in [`pipeline.go`](https://github.com/kunchenguid/no-mistakes/blob/main/pipeline.go) lines 254-260.

## Run Status Integration via IPC Events

The rendering system operates on an event-driven architecture rather than polling. Daemon events update the model state, which triggers the `View()` method to re-compose the display. The status integration follows this flow:

```

Model.View()
 ├─ renderPipelineBox()
 ├─ renderFindingsBox()   // or renderDiffBox() if showDiff
 │    └─ renderFindingsWithSelection() → renderFindingsRange()
 └─ renderActionBar()

```

This ensures that run status changes and new findings appear immediately without blocking the main thread.

## Summary

- The TUI uses Bubble Tea's model-view-update pattern with a three-panel layout composed in [`internal/tui/view.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/view.go)
- Pipeline status renders via `renderPipelineBox` in [`pipeline.go`](https://github.com/kunchenguid/no-mistakes/blob/main/pipeline.go), mapping `StepStatus` values to colored Unicode icons through the `statusIcon` function
- Findings render via [`review.go`](https://github.com/kunchenguid/no-mistakes/blob/main/review.go) functions that parse JSON, pre-select agent findings by default, and apply Lip-gloss styling with cursor and checkbox indicators
- Viewport handling in `renderFindingsViewport` manages long lists through `findingCursor` state stored in the model
- IPC events (`EventStepCompleted`) drive real-time updates to both status and findings, with `showDiff` controlling the findings/diff toggle

## Frequently Asked Questions

### How does the TUI switch between diff and findings views?

The `d` key toggles the `showDiff` boolean in the model. When true, the UI renders the diff view via `renderDiffBox`; otherwise, it displays the findings list. The action bar label updates dynamically to indicate the available toggle direction, as noted in [`pipeline.go`](https://github.com/kunchenguid/no-mistakes/blob/main/pipeline.go) lines 208-214.

### Where are the step status icons defined?

The `statusIcon` function in [`internal/tui/pipeline.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/pipeline.go) maps status constants like `StepStatusRunning` and `StepStatusSuccess` to Unicode symbols and colors around line 150.

### How does the TUI handle long lists of findings?

The `renderFindingsViewport` function limits the visible range based on terminal height and adds scroll indicators. Navigation state persists in `Model.findingCursor` and `Model.findingSelections`, with helper functions in [`findings.go`](https://github.com/kunchenguid/no-mistakes/blob/main/findings.go) managing the selection state.

### Which files handle the findings selection logic?

Selection state management resides in [`internal/tui/findings.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/findings.go) (lines 15-31), while the rendering logic with checkboxes and Lip-gloss styling is implemented in [`internal/tui/review.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/review.go) (lines 71-90).