# How the TUI Wizard in No-Mistakes Guides Users Through the Pipeline

> Explore how the no-mistakes TUI wizard simplifies Git workflows. Get real-time progress visualization, context-aware actions, and dynamic help for a streamlined pipeline experience.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: how-to-guide
- Published: 2026-07-02

---

**The TUI wizard in no-mistakes uses a Bubble Tea-based architecture to visualize pipeline progress in real-time, renders context-aware action bars when steps require human approval, and provides dynamically updated help overlays to guide users through deterministic Git workflows.**

The open-source **no-mistakes** repository implements an interactive terminal UI that transforms complex Git operations into a guided, keyboard-driven experience. Built with the Bubble Tea framework and styled with Lipgloss, the TUI wizard visualizes each pipeline stage—from intent and rebase to CI—while surfacing exactly the controls needed at each decision gate.

## Model-Driven State Management

The foundation of the wizard resides in [`internal/tui/app.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/app.go), where the root `Model` struct maintains the application state. This model tracks run information, step results, and UI flags including `showDiff`, `showHelp`, `confirmAbort`, and `yoloMode`.

When the program initializes via `Run` → `NewModel`, the system calls `normalizePipelineSteps` to ensure every known step—intent, rebase, review, test, lint, document, push, PR, and CI—appears in a deterministic order. This normalization guarantees that even if the backend daemon has not yet emitted events for later steps, the UI still displays the complete expected pipeline, preventing the interface from feeling incomplete.

The model subscribes to daemon events through `subscribeCmd` and updates its internal view on each `eventMsg`, ensuring the visualization remains synchronized with the actual execution state.

## Real-Time Pipeline Visualization

The visual representation of the pipeline lives in `renderPipelineView` within [`internal/tui/pipeline.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/pipeline.go). For each step, the renderer performs several formatting operations:

- **Status indicators**: The `stepStatusIndicator` function selects appropriate icons—spinners for running steps, ✓ for success, ✗ for failure, or ⏸ for paused states—based on the `types.StepStatus` enum.
- **Color coding**: The `stepStatusStyle` function applies semantic colors (blue for running, yellow for awaiting approval, green for success, red for failure).
- **Duration tracking**: Completed steps display their execution time via `formatDuration` applied to the `DurationMS` field.
- **Error surfacing**: When a step fails, the error message renders inline and truncates to fit the box width.
- **Connector logic**: Vertical connectors (`│`) draw between steps unless the terminal height falls below 30 rows, ensuring usability on compact screens.

The entire pipeline renders inside a bordered box created by `renderBox` and titled **Pipeline**, giving users an at-a-glance view of which stages have run, which are active, and where human input is required.

```go
// In internal/tui/app.go → NewModel: normalise steps so every known step is shown.
steps := normalizePipelineSteps(run.ID, run.Status, run.Steps)

// In internal/tui/pipeline.go → renderPipelineView: draw each step with spinner, label, duration.
icon := stepStatusIndicator(step.Status, spinnerFrame)
line := stepStatusStyle(step.Status).Render(icon) + " " + stepLabel(step.StepName)
if step.DurationMS != nil {
    line += "  " + dimStyle.Render(formatDuration(*step.DurationMS))
}
b.WriteString(line + "\n")

```

## Context-Aware Action Bars

When a step reaches a gate requiring user interaction—specifically `StepStatusAwaitingApproval` or `StepStatusFixReview`—the `renderActionBar` function constructs a bottom interaction bar. This bar adapts dynamically to the current context:

- **Prompt display**: Shows a label like "Rebase awaiting action:" or "Review - review fix:" derived from `stepLabel(step.StepName)`.
- **Primary actions**: Lists available keys including `a` (approve), `f` (fix), `s` (skip), and `x` (abort).
- **Diff toggle**: When a diff view is active, the bar includes the `d` key for toggling the view.
- **Selection mode**: If bulk selection is enabled, additional keys appear: `space` (or `\u2423` for toggle), `e` (edit), `+` (add), `A` (select all), and `N` (select none).

The action bar reflects the current UI state through flags like `showDiff`, `confirmAbort`, and `hasDiff`, ensuring users see only relevant actions and preventing invalid command attempts.

```go
// renderActionBar builds the bottom bar when a step is awaiting approval.
step := awaitingStep(steps)
prompt := fmt.Sprintf("%s awaiting action:", stepLabel(step.StepName))
b.WriteString(promptStyle.Render(prompt) + "\n")
b.WriteString(renderApprovalActions(...))

```

## Interactive Help System

Pressing `?` toggles the modal help overlay generated by `renderHelpOverlay`. Unlike static documentation, this overlay dynamically assembles sections based on the current run status:

- **Navigation shortcuts**: `j/k` for movement, `g/G` for top/bottom, `Ctrl+d/u` for page scrolling, and `n/p` when reviewing diffs.
- **Action shortcuts**: Contextual commands for approve, fix, skip, abort, and toggling diff/findings views.
- **Selection shortcuts**: Bulk operation keys available only when selection mode is active.
- **Footer shortcuts**: Global commands including `q` (quit/detach), `y` (yolo mode), and `r` (rerun).

The overlay also displays metadata such as the current branch, short commit hash, and pipeline ID, keeping situational awareness visible without cluttering the main workflow.

```go
// renderHelpOverlay adapts to the current UI mode.
if hasAwaitingStep {
    // navigation + actions + (selection or diff) sections
}
footer := []helpEntry{{"q", "quit"}, {"y", "yolo mode"}, …}
b.WriteString(renderEntries(footer))

```

## Event-Driven Updates

The model's `Update` method in [`internal/tui/app.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/app.go) serves as the central event router, processing three primary input types:

1. **Key presses**: Routed to `handleKey`, which toggles UI flags (e.g., `showDiff`, `showHelp`) or transmits approval/fix commands via the IPC client.
2. **Window resize**: Updates `width` and `height` fields so the pipeline view can responsively shrink or expand.
3. **Daemon events**: Each incoming event triggers `applyEvent` to update step results. When a step finishes, the `hasSpinningStep` check stops the spinner, and `renderOutcomeBanner` displays a final status line.

After pipeline termination, `renderOutcomeBanner` renders a one-line summary (e.g., "✓ Pipeline passed") alongside the total elapsed time, providing a definitive visual cue that the wizard has completed.

## Summary

- The **no-mistakes** TUI wizard uses a **model-driven architecture** in [`internal/tui/app.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/app.go) to maintain deterministic step ordering and UI state.
- **Real-time visualization** via `renderPipelineView` combines status icons, color coding, and duration formatting to communicate progress instantly.
- **Context-aware action bars** appear only when steps reach `AwaitingApproval` or `FixReview` states, surfacing precise controls (`a`, `f`, `s`, `x`) for the current decision point.
- **Dynamic help overlays** adapt to the current mode, showing only relevant keyboard shortcuts and pipeline metadata.
- **Event-driven updates** ensure the UI remains synchronized with the backend daemon through IPC messages and responsive to terminal resizes.

## Frequently Asked Questions

### How does the TUI wizard maintain step order when the backend hasn't emitted all events?

The wizard calls `normalizePipelineSteps` during initialization in [`internal/tui/app.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/app.go) to pre-populate the complete list of known steps—including intent, rebase, review, test, lint, document, push, PR, and CI—in a deterministic order. This ensures the UI never appears sparse or incomplete, even when the daemon has only reported early stages.

### What keyboard shortcuts are available when a step requires approval?

When a step reaches `StepStatusAwaitingApproval`, the action bar displays `a` to approve, `f` to fix, `s` to skip, and `x` to abort. If a diff view is active, `d` toggles the display. In selection mode, additional keys include `space` to toggle items, `e` to edit, `+` to add, `A` to select all, and `N` to select none.

### How does the TUI wizard communicate with the no-mistakes daemon?

The model subscribes to daemon events via `subscribeCmd` and processes them through `applyEvent` in the `Update` method. User actions like approvals or fixes transmit back to the daemon through an IPC client, creating a bidirectional event stream that keeps the visualization synchronized with actual execution.

### What visual feedback indicates a completed or failed pipeline?

The `renderOutcomeBanner` function in [`internal/tui/pipeline.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/tui/pipeline.go) displays a one-line summary at the bottom of the terminal when execution finishes. Successful runs show a checkmark with "Pipeline passed," while failures display an error indicator with the total duration, giving immediate closure to the workflow.