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

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, 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. 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.

// 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.

// 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.

// 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 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 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 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →