-
Notifications
You must be signed in to change notification settings - Fork 9
TUI Dashboard for Parallel Task Execution #82
Description
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:
- Status icon:
✓pass,✗fail,◐running (animated),○pending - Task name: The task identifier
- Host: Which host is running it (or "queued" if pending)
- Duration: Elapsed time for completed/running tasks
- 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
- Orchestrator sends
TaskEventthrough channel - Dashboard receives as Bubble Tea
Cmd - Model updates task state
- 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
- Many tasks: Scrollable list when tasks exceed terminal height
- Long output: Ring buffer prevents memory issues; full output optional
- Fast completion: Brief flash of "running" state is OK
- Terminal resize: Recalculate layout, preserve selection
- Quit during execution: Confirm dialog, cancel running tasks
- 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:
- Create
model.gowith Bubble Tea Model struct - Create
types.gowith TaskState, TaskEvent, etc. - Create
messages.gowith Bubble Tea message types - Implement Init(), Update(), View() skeleton
Verify: go build ./internal/parallel/dashboard/...
Task 2: Task List View
Context: internal/parallel/dashboard/
Steps:
- Create
view_list.gowith list rendering - Implement responsive layouts (minimal, compact, standard, wide)
- Add status indicators with animations
- Implement keyboard navigation
Verify: Unit tests for layout at different widths
Task 3: Detail View with Viewport
Context: internal/parallel/dashboard/
Steps:
- Create
view_detail.gowith task output view - Integrate bubbles/viewport for scrolling
- Implement follow mode (auto-scroll)
- 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:
- Add event channel to orchestrator
- Create Bubble Tea Cmd that reads from channel
- Update model state on events
- Handle event ordering (started before output)
Verify: Events flow correctly from orchestrator to dashboard
Task 5: Summary View
Context: internal/parallel/dashboard/
Steps:
- Create
view_summary.gofor completion state - Show aggregate statistics
- Highlight failures prominently
- Add retry suggestions
Verify: Summary displays correctly after completion
Task 6: Non-TTY Fallback
Context: internal/parallel/
Steps:
- Detect TTY with
term.IsTerminal() - Create simple streaming output for non-TTY
- Use existing prefixed output from parallel plan
- 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)