Skip to content

TUI Dashboard for Parallel Task Execution #82

@rileyhilliard

Description

@rileyhilliard

Parallel Task Dashboard (TUI) Design

Status: DRAFT
Related: #81 (Parallel Task Execution)

Overview

A real-time TUI dashboard for monitoring parallel task execution. Shows per-task status, host assignment, and live output in a clean, information-dense interface using Bubble Tea.

Design Philosophy

  • Glanceable status: See overall progress and identify problems instantly
  • Progressive disclosure: Summary view by default, drill into output when needed
  • Consistent patterns: Reuse existing monitor UI components and responsive layouts
  • Minimal chrome: Information density over decoration

Information Architecture

Primary View: Task List

The default view is a compact list showing all tasks with their status:

 Parallel Tasks                                    2/4 complete | 12.3s
────────────────────────────────────────────────────────────────────────
 ✓ test-cli      m1-mini     3.2s    passed
 ✓ test-host     m1-linux    4.1s    passed
 ◐ test-exec     m4-mini     8.1s    running...
 ○ test-sync     (queued)    -       pending
────────────────────────────────────────────────────────────────────────
 ↑↓ select | Enter expand | q quit | ? help

Columns:

  1. Status icon: pass, fail, running (animated), pending
  2. Task name: The task identifier
  3. Host: Which host is running it (or "queued" if pending)
  4. Duration: Elapsed time for completed/running tasks
  5. Status text: "passed", "failed (exit 1)", "running...", "pending"

Detail View: Task Output

Press Enter on a task to expand its output:

 test-exec on m4-mini                              running... 8.1s
────────────────────────────────────────────────────────────────────────
 === RUN   TestExecuteTask
 === RUN   TestExecuteTask/single_command
 === RUN   TestExecuteTask/multi_step_task
 --- PASS: TestExecuteTask (0.12s)
     --- PASS: TestExecuteTask/single_command (0.04s)
     --- PASS: TestExecuteTask/multi_step_task (0.08s)
 === RUN   TestBuildCommand
 |
────────────────────────────────────────────────────────────────────────
 Esc back | ↑↓ scroll | f follow | q quit

Features:

  • Scrollable viewport (uses bubbles/viewport)
  • "Follow" mode auto-scrolls to bottom (like tail -f)
  • Shows last N lines of output (configurable buffer)
  • For completed tasks, shows full captured output

Summary View: Final Results

After all tasks complete, show aggregate results:

 Parallel Tasks Complete                           3 passed, 1 failed
────────────────────────────────────────────────────────────────────────
 ✓ test-cli      m1-mini     3.2s    passed
 ✓ test-host     m1-linux    4.1s    passed
 ✓ test-exec     m4-mini    12.4s    passed
 ✗ test-sync     m1-mini     2.1s    failed (exit 1)
────────────────────────────────────────────────────────────────────────
 Total: 21.7s (wall), 48.3s (cumulative) | 3 hosts used

 Failed: test-sync
 Run `rr test-sync` to retry
────────────────────────────────────────────────────────────────────────
 Enter view output | q quit

Responsive Layouts

Following the monitor pattern, adapt to terminal size:

Wide (160+ cols): Two-column

┌─────────────────────────────────┐ ┌─────────────────────────────────┐
│ Task List                       │ │ Selected Task Output            │
│ ✓ test-cli    m1-mini    3.2s   │ │ === RUN TestFoo                 │
│ ◐ test-exec   m4-mini    8.1s ◄─┼─│ === RUN TestBar                 │
│ ○ test-sync   (queued)          │ │ --- PASS: TestFoo (0.1s)        │
└─────────────────────────────────┘ └─────────────────────────────────┘

Standard (120-160 cols): List with inline status

 ✓ test-cli      m1-mini       3.2s    passed     === RUN TestCli...
 ◐ test-exec     m4-mini       8.1s    running    === RUN TestExec...
 ○ test-sync     (queued)      -       pending

Compact (80-120 cols): Simple list

 ✓ test-cli    m1-mini   3.2s  passed
 ◐ test-exec   m4-mini   8.1s  running
 ○ test-sync   queued    -     pending

Minimal (<80 cols): Ultra-compact

 ✓ test-cli    3.2s
 ◐ test-exec   8.1s
 ○ test-sync   -

Status Indicators

Reuse colors from existing UI (internal/ui/colors.go):

State Icon Color Animation
Pending Muted gray None
Running Accent blue Spinner rotation: ◐◓◑◒
Passed Success green None
Failed Error red None
Cancelled Warning yellow None

Interaction Model

Keyboard Shortcuts

Key Action
/ or j/k Navigate task list
Enter Expand selected task (show output)
Esc Collapse back to list view
f Toggle follow mode in detail view
q Quit (with confirmation if tasks running)
? Toggle help overlay

Non-Interactive Mode

When stdout is not a TTY (piped output), fall back to simple streaming:

[test-cli:m1-mini] Starting...
[test-cli:m1-mini] === RUN TestFoo
[test-exec:m4-mini] Starting...
[test-cli:m1-mini] --- PASS: TestFoo
[test-cli] ✓ passed (3.2s)
[test-exec:m4-mini] === RUN TestBar
...

Data Flow

┌─────────────────┐
│   Orchestrator  │
│  (parallel pkg) │
└────────┬────────┘
         │ TaskEvent channel
         ▼
┌─────────────────┐
│   Dashboard     │
│   Model         │
│  (Bubble Tea)   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│   View          │
│  (lipgloss)     │
└─────────────────┘

Event Types

type TaskEvent struct {
    Type      EventType  // Started, Output, Completed, Failed
    TaskName  string
    Host      string     // For Started
    Output    string     // For Output (line of stdout/stderr)
    ExitCode  int        // For Completed/Failed
    Duration  time.Duration
    Error     error      // For Failed
}

Message Flow

  1. Orchestrator sends TaskEvent through channel
  2. Dashboard receives as Bubble Tea Cmd
  3. Model updates task state
  4. View re-renders

Output Buffering

Each task maintains a ring buffer of output lines:

type TaskState struct {
    Name       string
    Host       string
    Status     TaskStatus
    StartTime  time.Time
    Duration   time.Duration
    ExitCode   int

    // Output buffering
    OutputBuffer *RingBuffer  // Last N lines for live view
    FullOutput   *bytes.Buffer // Complete output (if configured)
}

Buffer sizing:

  • Live view: Last 1000 lines in ring buffer (configurable)
  • Full capture: Optional, disabled by default to save memory
  • On completion: Option to dump full output to file

Component Reuse

Leverage existing components from internal/ui/ and internal/monitor/:

Component Source Usage
Color palette ui/colors.go Consistent styling
Spinner animation ui/bubbles_spinner.go Running task indicator
Viewport bubbles/viewport Scrollable output
Layout breakpoints monitor/model.go Responsive design
Card styling monitor/styles.go Task panels

Edge Cases

  1. Many tasks: Scrollable list when tasks exceed terminal height
  2. Long output: Ring buffer prevents memory issues; full output optional
  3. Fast completion: Brief flash of "running" state is OK
  4. Terminal resize: Recalculate layout, preserve selection
  5. Quit during execution: Confirm dialog, cancel running tasks
  6. Host failure: Show error inline with task, mark as failed

Configuration

Integrate with existing output config:

output:
  parallel_dashboard: auto  # auto, always, never
  # auto: TUI if TTY, streaming if piped

  dashboard:
    follow: true           # Auto-scroll in detail view
    buffer_lines: 1000     # Lines to keep in memory per task
    capture_full: false    # Keep complete output (memory intensive)

Implementation Tasks

Task 1: Dashboard Model and Types

Context: internal/parallel/dashboard/

Steps:

  1. Create model.go with Bubble Tea Model struct
  2. Create types.go with TaskState, TaskEvent, etc.
  3. Create messages.go with Bubble Tea message types
  4. Implement Init(), Update(), View() skeleton

Verify: go build ./internal/parallel/dashboard/...


Task 2: Task List View

Context: internal/parallel/dashboard/

Steps:

  1. Create view_list.go with list rendering
  2. Implement responsive layouts (minimal, compact, standard, wide)
  3. Add status indicators with animations
  4. Implement keyboard navigation

Verify: Unit tests for layout at different widths


Task 3: Detail View with Viewport

Context: internal/parallel/dashboard/

Steps:

  1. Create view_detail.go with task output view
  2. Integrate bubbles/viewport for scrolling
  3. Implement follow mode (auto-scroll)
  4. Handle transition between list and detail views

Verify: Scrolling works with large output


Task 4: Event Integration

Context: internal/parallel/dashboard/, internal/parallel/orchestrator.go

Steps:

  1. Add event channel to orchestrator
  2. Create Bubble Tea Cmd that reads from channel
  3. Update model state on events
  4. Handle event ordering (started before output)

Verify: Events flow correctly from orchestrator to dashboard


Task 5: Summary View

Context: internal/parallel/dashboard/

Steps:

  1. Create view_summary.go for completion state
  2. Show aggregate statistics
  3. Highlight failures prominently
  4. Add retry suggestions

Verify: Summary displays correctly after completion


Task 6: Non-TTY Fallback

Context: internal/parallel/

Steps:

  1. Detect TTY with term.IsTerminal()
  2. Create simple streaming output for non-TTY
  3. Use existing prefixed output from parallel plan
  4. Integrate with orchestrator's output mode

Verify: Works correctly when piped to file


Future Enhancements

  • Live CPU/memory per task (from host metrics)
  • Task duration estimates based on history
  • Output search/filter in detail view
  • Export output to file on demand
  • Notification hooks (sound, desktop notification on completion)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions