# 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
```bash
# 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
```rust
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
```rust
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
```rust
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
```rust
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:
```rust
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
```rust
// 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
```bash
# 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
```rust
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
| `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
```rust
pub enum View {
Kanban, // Kanban board
Agents, // Agent status
Logs, // Event logs
Graph, // Dependency graph
}
```
### Layout Modes
```rust
pub enum LayoutMode {
Full, // ≥120 columns: sidebar + main
Compact, // 80-119 columns: main only
Mobile, // <80 columns: minimal
}
```
## Troubleshooting
### Terminal rendering issues
```bash
# Set TERM variable
export TERM=xterm-256color
# Clear screen
clear
# Reset terminal state
reset
```
### Colors not working
```rust
// 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:
```bash
tput cnorm # Make cursor visible
```
## Related Crates
- **[flow-core](../flow-core/README.md)**: Feature and Task types
- **[flow-db](../flow-db/README.md)**: Database backend for features
- **[flow-server](../flow-server/README.md)**: Web server alternative
- **Ratatui**: Terminal UI library ([docs](https://docs.rs/ratatui))
- **Crossterm**: Cross-platform terminal manipulation ([docs](https://docs.rs/crossterm))
[Back to main README](../../README.md)