How the No-Mistakes TUI Integrates with the Pipeline and Daemon
The no-mistakes terminal user interface (TUI) is a thin, event-driven front-end that visualizes and controls the underlying pipeline execution through real-time state synchronization with the background daemon.
The kunchenguid/no-mistakes repository implements a terminal-based workflow manager where the TUI serves as a visual control plane for the headless daemon process. Understanding how the TUI integrates with the pipeline and daemon reveals an architecture built on gRPC state streams, read-only rendering, and bidirectional command forwarding.
Architecture Overview
The integration follows a client-server model where the daemon maintains the single source of truth. The TUI never executes pipeline logic locally; instead, it subscribes to state changes and forwards user commands via an IPC channel.
- The daemon manages pipeline execution, file system watching, and git operations
- The TUI provides real-time visualization and user interaction
- Communication occurs through protocol buffer definitions with gRPC streaming
Launching the TUI: The Attach Command
Entry into the TUI begins with the no-mistakes attach CLI command implemented in internal/cli/attach.go. This command ensures the daemon is running before initializing the interface.
// internal/cli/attach.go
runTUI = tui.Run // exported variable, replaceable in tests
...
func attachRun(cmd *cobra.Command, args []string) error {
// ... ensure daemon is reachable ...
return runTUI(ctx, client, runID) // start TUI with IPC client
}
The attachRun function performs three critical steps:
- Verifies daemon availability through the singleton lock mechanism
- Establishes a gRPC client connection via
internal/daemon/client.go - Invokes
tui.Runwith the active run ID to begin the event loop
State Propagation: Real-Time Synchronization
State synchronization relies on the internal/daemon/state package, which defines the shared State struct streamed from daemon to TUI. In internal/tui/app.go, the application creates a state.Listener that subscribes to the daemon's StateStream.
// internal/tui/app.go (simplified)
func (a *app) watchState(ctx context.Context, client *daemon.Client) {
stream, _ := client.StateStream(ctx, &daemon.StateRequest{})
for {
s, err := stream.Recv()
if err != nil { return }
a.mu.Lock()
a.state = s // store latest snapshot
a.mu.Unlock()
a.render() // trigger UI redraw
}
}
The watchState loop blocks on stream.Recv(), updating app.state atomically whenever the daemon emits new data. This includes pipeline step transitions, new findings, or branch-sync events. The mutex-protected a.state ensures thread-safe access between the gRPC receive loop and the UI rendering thread.
Rendering the Pipeline
The internal/tui/pipeline.go view renders the state.Pipeline object, mapping each pipeline.Step struct to visual components. The TUI implements selective redraws using tuiRelevantSyncState guards to ignore updates from unrelated runs.
// internal/tui/pipeline.go (excerpt)
func (p *pipelineView) Draw(s tcell.Screen) {
steps := a.state.Pipeline.Steps
for i, step := range steps {
style := stepStyle(step.Status) // success / running / failed
s.SetContent(x, y+i, rune(step.Icon), nil, style)
}
}
Each step status—review, lint, test, or push—translates to distinct visual indicators. The view reacts immediately when the daemon updates state.Pipeline.RunID or modifies step completion states.
Command Handling: User Input to Daemon Execution
User interactions flow in the reverse direction, from TUI to daemon. Keystrokes mapped in keys.go dispatch to handlers in internal/tui/commands.go, which invoke gRPC methods on the daemon client.
// internal/tui/commands.go (partial)
func (a *app) handleKey(k tcell.Key) {
switch k {
case tcell.KeyF5: // "sync"
a.client.SyncBranch(context.Background(), &daemon.SyncRequest{RunID: a.state.Pipeline.RunID})
case tcell.KeyCtrlC: // "abort"
a.client.AbortRun(context.Background(), &daemon.AbortRequest{RunID: a.state.Pipeline.RunID})
}
}
Common commands include:
- Retry: Resubmit failed pipeline steps
- Abort: Cancel the current run via
AbortRun - Sync: Trigger branch synchronization via
SyncBranch
The daemon enqueues these operations, updates the shared state, and the new state streams back to the TUI, completing the feedback loop.
Specialized Views: Branch Sync and Findings
Beyond the main pipeline view, the TUI integrates specialized components for specific daemon operations.
Branch Synchronization
The internal/tui/branch_sync.go view listens for branchsync.State emissions from the daemon. It renders progress bars during sync operations and highlights stale-error conditions detected in stale_error_test.go scenarios.
Findings and Reviews
The findings system demonstrates bidirectional data flow:
- The daemon populates
state.Findingswith lint errors and review comments internal/tui/findings.gorenders the slice as an interactive list- The
review.goview allows users to approve, reject, or edit findings - These actions post back to the daemon via the same RPC channel established in
attach.go
Lifecycle Coordination and Error Handling
The TUI respects the daemon's singleton lock defined in internal/daemon/lock.go. If the daemon process terminates unexpectedly, the TUI detects the closed gRPC stream, displays a terminal error message, and exits gracefully.
Conversely, the daemon can request TUI shutdown by emitting a state.Shutdown flag in the state stream. This occurs after successful pipeline completion or when the daemon requires a hard restart for configuration changes.
Summary
- The TUI is a read-only renderer of daemon state, ensuring the pipeline and daemon remain the single source of truth
- State synchronization occurs through gRPC streaming via
state.Listenerininternal/tui/app.go - User commands forward to the daemon through
internal/daemon/client.goRPC methods - The attach command (
internal/cli/attach.go) establishes the initial IPC channel and validates daemon health - Specialized views handle branch-sync progress and finding reviews through the same bidirectional channel
- Lifecycle management includes graceful handling of daemon crashes and coordinated shutdown sequences
Frequently Asked Questions
How does the TUI initially connect to the daemon?
The no-mistakes attach command in internal/cli/attach.go verifies the daemon is running through the singleton lock mechanism, then establishes a gRPC client connection before invoking tui.Run with the active run ID and client instance.
What happens when the daemon updates pipeline state?
The daemon emits a new State protobuf message through the StateStream RPC. The TUI's watchState loop in internal/tui/app.go receives this message, updates the mutex-protected app.state field, and triggers a UI redraw to reflect the new pipeline step statuses.
Can the TUI control pipeline execution or is it read-only?
While primarily a read-only renderer, the TUI supports bidirectional control. User keystrokes mapped in keys.go dispatch commands via internal/tui/commands.go that send gRPC requests—such as AbortRun or SyncBranch—to the daemon, which then executes the requested operations.
How does the TUI handle daemon crashes or unexpected disconnections?
If the daemon terminates, the gRPC stream closes and stream.Recv() in watchState returns an error. The TUI detects this closure, displays an error message to the user, and exits gracefully rather than attempting to reconnect or continue with stale data.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →