#ai-agent #kanban #dashboard #ratatui

bin+lib flow-tui

Terminal UI for Flow with Kanban board, agent status, and dependency graph views

2 releases

0.1.2 Feb 7, 2026
0.1.1 Feb 7, 2026

#2938 in Command line utilities


Used in agentflow-cli

MIT license

210KB
4K SLoC

flow-tui

Beautiful terminal-based user interface for feature management, built with Ratatui and Crossterm.

What it does

flow-tui is a full-screen terminal application that turns your command line into an interactive dashboard. Think of it like Spotify's terminal interface or htop, but for managing features and tasks.

Instead of opening a web browser, you get a native terminal experience with:

  • Kanban board with drag-and-drop feel (keyboard navigation)
  • Dependency graph visualization (ASCII art)
  • Live agent status showing what multiple AI agents are working on
  • Event logs showing real-time updates
  • Responsive layout that adapts to your terminal size

It's perfect for developers who live in the terminal and want to stay in their flow state.

Architecture

flow-tui/
├── main.rs             - Entry point and event loop
├── lib.rs              - Module exports
├── app.rs              - Application state and logic
├── theme.rs            - Color schemes and styling
├── input.rs            - Keyboard event handling
└── views/
    ├── mod.rs          - View organization
    ├── kanban.rs       - Kanban board view
    ├── agents.rs       - Agent status view
    ├── logs.rs         - Event log view
    ├── graph.rs        - Dependency graph view
    └── help.rs         - Help screen

View Architecture

Terminal Screen
     ↓
Current View (Kanban, Agents, Logs, Graph)
     ↓
Ratatui Widgets (Table, Block, Paragraph)
     ↓
Theme Colors (Dark, Light, Solarized)

Usage

Running the TUI

# Build and run
cargo run -p flow-tui

# Or install and run
cargo install --path crates/flow-tui
flow-tui

Keyboard Controls

Global Controls:

  • ? - Toggle help screen
  • q or Ctrl+C - Quit application
  • Tab - Cycle through views
  • 1 - Switch to Kanban view
  • 2 - Switch to Agents view
  • 3 - Switch to Logs view
  • 4 - Switch to Graph view
  • t - Cycle through themes

Navigation:

  • j or Down - Move selection down
  • k or Up - Move selection up
  • PageDown - Scroll down one page
  • PageUp - Scroll up one page
  • Home - Go to top
  • End - Go to bottom

Kanban View:

  • Enter - View feature details
  • Space - Toggle feature status
  • d - Mark as done
  • i - Mark in progress
  • f - Mark as failing

Graph View:

  • + - Zoom in
  • - - Zoom out
  • Arrow keys - Pan around

Views

Kanban Board

┌─ Kanban View ────────────────────────────────────┐
│                                                   │
│  BACKLOG          IN PROGRESS        DONE         │
│  ┌──────────┐     ┌──────────┐     ┌──────────┐  │
│  │ Feature 1│     │ Feature 3│     │ Feature 5│  │
│  │ ⚡ High  │     │ 🔄 50%   │     │ ✓        │  │
│  └──────────┘     └──────────┘     └──────────┘  │
│  ┌──────────┐     ┌──────────┐     ┌──────────┐  │
│  │ Feature 2│     │ Feature 4│     │ Feature 6│  │
│  │ ⬇️ 1 dep │     │ ⬇️ 2 dep│     │ ✓        │  │
│  └──────────┘     └──────────┘     └──────────┘  │
│                                                   │
└───────────────────────────────────────────────────┘

Features organized by status:

  • Backlog: Not started
  • In Progress: Currently being worked on
  • Done: Completed and passing

Agent Status

┌─ Agent Status ───────────────────────────────────┐
│                                                   │
│  AGENT     STATUS      TASK           UPTIME      │
│  ───────────────────────────────────────────────  │
│  🤖 claude  Working    OAuth impl     2h 15m      │
│  🤖 codex   Idle       -              1h 45m      │
│  🤖 gemini  Working    UI tests       0h 30m      │
│                                                   │
│  Throughput: 3.2 tasks/hour                       │
│  Active: 2/3 agents                               │
│                                                   │
└───────────────────────────────────────────────────┘

Real-time monitoring of AI agent activity.

Logs View

┌─ Event Logs ─────────────────────────────────────┐
│                                                   │
│  14:23:45  [INFO] Feature #42 marked as passing   │
│  14:23:40  [WARN] Feature #12 has failing tests   │
│  14:23:35  [INFO] Agent 'claude' claimed task 15  │
│  14:23:30  [INFO] 3 new features created          │
│  14:23:25  [DEBUG] Database backup completed      │
│                                                   │
│  [Auto-scroll: ON] [Filter: ALL]                  │
│                                                   │
└───────────────────────────────────────────────────┘

Scrollable event history with filtering.

Dependency Graph

┌─ Dependency Graph ───────────────────────────────┐
│                                                   │
│      [1] Auth                                     │
│       ├─> [2] Login UI                            │
│       │    └─> [5] Dashboard                      │
│       └─> [3] Rate Limiting                       │
│            └─> [4] Tests                          │
│                                                   │
│  Legend: ✓ Done  🔄 In Progress  ⚠️ Blocked        │
│                                                   │
└───────────────────────────────────────────────────┘

ASCII visualization of feature dependencies.

Themes

Built-in Themes

pub enum Theme {
    Dark,       // Dark background, light text
    Light,      // Light background, dark text
    Solarized,  // Solarized color scheme
    Monokai,    // Monokai editor theme
    Nord,       // Nord color palette
}

Theme Cycling

Press t to cycle through themes:

  • Dark → Light → Solarized → Monokai → Nord → Dark

Custom Theme Colors

pub struct TuiTheme {
    pub bg: Color,
    pub fg: Color,
    pub border: Color,
    pub highlight: Color,
    pub success: Color,
    pub warning: Color,
    pub error: Color,
    pub info: Color,
}

// Example: Create custom theme
let custom_theme = TuiTheme {
    bg: Color::Rgb(0x1e, 0x1e, 0x2e),
    fg: Color::Rgb(0xcd, 0xdc, 0xfe),
    border: Color::Rgb(0x6c, 0x71, 0xc4),
    highlight: Color::Rgb(0xf3, 0x8b, 0xa8),
    success: Color::Rgb(0xa3, 0xbe, 0x8c),
    warning: Color::Rgb(0xeb, 0xcb, 0x8b),
    error: Color::Rgb(0xbf, 0x61, 0x6a),
    info: Color::Rgb(0x88, 0xc0, 0xd0),
};

Responsive Layout

The TUI automatically adapts to your terminal size:

Full Layout (≥120 columns)

┌───────────────────────────────────────────────────┐
│  Header with stats and navigation tabs            │
├───────────────────────────────────────────────────┤
│  Sidebar   │  Main Content Area (Kanban/Logs)     │
│  - Stats   │                                       │
│  - Filters │                                       │
│  - Actions │                                       │
└───────────────────────────────────────────────────┘

Compact Layout (80-119 columns)

┌────────────────────────────────┐
│  Header                        │
├────────────────────────────────┤
│  Main Content (full width)     │
│                                │
│  Stats shown in header         │
└────────────────────────────────┘

Mobile Layout (<80 columns)

┌──────────────┐
│  Header      │
├──────────────┤
│  Content     │
│  (minimal)   │
│              │
└──────────────┘

Integration with Database

use flow_tui::app::App;
use flow_db::Database;

#[tokio::main]
async fn main() -> Result<()> {
    // Open database
    let db = Database::open("features.db")?;

    // Create TUI app
    let mut app = App::new();

    // Load features from database
    let conn = db.writer().lock().unwrap();
    app.features = FeatureStore::get_all(&conn)?;

    // Run TUI event loop
    run_tui(&mut app).await?;

    Ok(())
}

Code Example: Custom View

use ratatui::{Frame, layout::{Constraint, Direction, Layout}, widgets::{Block, Borders, Paragraph}};
use crate::app::App;

pub fn render_custom_view(frame: &mut Frame, app: &App) {
    let area = frame.area();

    // Create layout
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Length(3),  // Header
            Constraint::Min(0),     // Content
            Constraint::Length(3),  // Footer
        ])
        .split(area);

    // Header
    let header = Block::default()
        .borders(Borders::ALL)
        .border_style(app.tui_theme.border)
        .title("My Custom View");
    frame.render_widget(header, chunks[0]);

    // Content
    let content = Paragraph::new("Hello from custom view!")
        .style(app.tui_theme.fg);
    frame.render_widget(content, chunks[1]);

    // Footer
    let footer = Paragraph::new("Press ? for help")
        .style(app.tui_theme.info);
    frame.render_widget(footer, chunks[2]);
}

Event Loop

The TUI uses a hybrid event-driven architecture:

use crossterm::event::{self, Event, KeyCode};
use ratatui::Terminal;
use std::time::Duration;

pub async fn run_tui(app: &mut App) -> Result<()> {
    let mut terminal = setup_terminal()?;

    loop {
        // Render current frame
        terminal.draw(|f| app.render(f))?;

        // Wait for event with timeout (for animation/updates)
        if event::poll(Duration::from_millis(100))? {
            if let Event::Key(key) = event::read()? {
                if app.handle_key(key) {
                    break; // Quit requested
                }
            } else if let Event::Resize(w, h) = event::read()? {
                app.resize(w, h);
            }
        }

        // Update state (e.g., check for DB changes)
        app.tick().await?;
    }

    cleanup_terminal()?;
    Ok(())
}

Performance

  • Render time: ~2-5ms per frame
  • Input latency: <10ms
  • Memory usage: ~5MB for 1000 features
  • Supports: Up to 10,000 features before noticeable lag

Optimization Tips

// Use double-buffering (built into Ratatui)
// Only redraw on changes
if app.needs_redraw() {
    terminal.draw(|f| app.render(f))?;
}

// Limit log history
if app.log_messages.len() > 100 {
    app.log_messages.drain(0..10); // Remove oldest 10
}

// Virtualize large lists (only render visible items)
let visible_range = app.scroll_offset..(app.scroll_offset + terminal_height);
let visible_features = &app.features[visible_range];

Testing

# Run TUI tests
cargo test -p flow-tui

# Run with test TUI backend (doesn't require terminal)
cargo test -p flow-tui -- --nocapture

# Manual testing in isolated terminal
cargo run -p flow-tui

Integration Testing

use ratatui::backend::TestBackend;
use ratatui::Terminal;

#[test]
fn test_kanban_render() {
    let backend = TestBackend::new(80, 24);
    let mut terminal = Terminal::new(backend).unwrap();
    let mut app = App::new();

    terminal.draw(|f| app.render(f)).unwrap();

    let buffer = terminal.backend().buffer();
    // Assert buffer contains expected content
    assert!(buffer.content().contains("Kanban"));
}

API Reference

App Methods

Method Description
App::new() Create new app with default state
app.render(frame) Render current view to terminal
app.handle_key(key) Process keyboard input, returns true if quitting
app.resize(width, height) Handle terminal resize
app.add_log(message) Add message to event log
app.load_demo_data() Load sample features for testing

View Enum

pub enum View {
    Kanban,   // Kanban board
    Agents,   // Agent status
    Logs,     // Event logs
    Graph,    // Dependency graph
}

Layout Modes

pub enum LayoutMode {
    Full,     // ≥120 columns: sidebar + main
    Compact,  // 80-119 columns: main only
    Mobile,   // <80 columns: minimal
}

Troubleshooting

Terminal rendering issues

# Set TERM variable
export TERM=xterm-256color

# Clear screen
clear

# Reset terminal state
reset

Colors not working

// Check terminal color support
if crossterm::tty::IsTty::is_tty(&std::io::stdout()) {
    println!("Terminal supports colors");
} else {
    println!("Terminal does not support colors");
}

Cursor remains visible

The TUI automatically hides the cursor on startup and restores it on exit. If it doesn't, run:

tput cnorm  # Make cursor visible
  • flow-core: Feature and Task types
  • flow-db: Database backend for features
  • flow-server: Web server alternative
  • Ratatui: Terminal UI library (docs)
  • Crossterm: Cross-platform terminal manipulation (docs)

Back to main README

Dependencies

~37–53MB
~790K SLoC