Roxid
A Terminal User Interface (TUI) application built with Ratatui for managing and executing YAML-based pipelines via gRPC.
Table of Contents
- Features
- Quick Start
- Installation
- Usage
- Architecture
- Pipeline System
- TUI Guide
- Extending the Application
- Project Structure
- Resources
Features
TUI Features
- Pipeline Discovery: Automatically discovers pipeline YAML files in the current directory
- Interactive Selection: Navigate through available pipelines with keyboard controls
- Real-time Execution: Execute pipelines with live progress tracking via gRPC streaming
- Progress Visualization: Visual progress bar showing current step
- Live Output: Real-time output display during pipeline execution
- Error Handling: Uses color-eyre for better error reporting
- Cross-platform: Works on Linux, macOS, and Windows
Pipeline Features
- YAML-based pipeline definitions: Simple, declarative syntax
- Command and shell script execution: Run single commands or multi-line scripts
- Environment variable support: Pipeline-level and step-level env vars
- Real-time progress reporting: Live updates via gRPC streaming
- Error handling: Continue on error support for non-critical steps
gRPC Service
- Remote execution: Pipeline execution via gRPC service
- Streaming updates: Real-time execution events streamed to clients
- Language-agnostic: Any language with gRPC support can be a client
- Scalable architecture: Service can be deployed independently
Quick Start
Just run roxid - the service auto-starts and auto-stops!
# Launch TUI (auto-starts service, stops when you quit)
# Or run a specific pipeline (auto-starts service, stops when done)
That's it! The service automatically starts when needed and stops when you're done.
For more details, see the Usage section below.
Installation
Option 1: From crates.io (Recommended)
Option 2: Pre-built Binary
Download from Releases:
- Linux x86_64:
roxid-linux-x86_64.tar.gz - macOS Intel:
roxid-macos-x86_64.tar.gz - macOS Apple Silicon:
roxid-macos-aarch64.tar.gz - Windows:
roxid-windows-x86_64.exe.zip
Linux/macOS:
Windows: Extract ZIP and add to PATH.
Option 3: From Git
Option 4: Build from Source
Verify
Uninstall
# If installed via cargo:
# If installed manually:
Usage
The Simplest Way
Just type roxid - service starts automatically and stops when you're done!
# Launch TUI
# Or run a pipeline
Smart service management:
- If service isn't running → starts it for you
- When you quit/finish → stops it automatically
- If service was already running → leaves it running
TUI Controls
Pipeline List Screen:
↑ork- Move selection up↓orj- Move selection downEnter- Execute selected pipelineqorEsc- Quit application
Pipeline Execution Screen:
qorEsc- Return to pipeline list (only after completion)
CLI Pipeline Execution
Run pipelines directly from command line:
Alternative: Manual Service Management
For development or debugging, you can manage the service manually:
# Terminal 1: Start service
# Terminal 2: Run TUI or CLI
Alternative: Auto-Start Scripts
If running from source, convenience scripts are available:
Troubleshooting
"Connection refused" error:
- The service isn't running
- Solution: Just run
roxid- it auto-starts the service
"Address already in use" error:
- Another service instance is running
- Solution:
pkill -f pipeline-servicethen retry
"No such file or directory" when parsing pipeline:
- Pipeline file not found
- Solution: Use absolute path or run from correct directory
Service Management
# Check if service is running
# Stop service manually (if needed)
# View service logs (when using scripts)
Architecture
Workspace Structure
This workspace follows a gRPC-based microservice architecture:
roxid/
├── Cargo.toml # Workspace manifest
├── pipeline-service/ # gRPC service (library + binary)
│ ├── Cargo.toml
│ ├── build.rs # Proto compilation
│ ├── proto/
│ │ └── pipeline.proto # gRPC service definition
│ └── src/
│ ├── lib.rs # Library entry point
│ ├── grpc.rs # Proto conversions and types
│ ├── error.rs # Error types
│ ├── pipeline/ # Pipeline execution engine
│ └── bin/
│ └── server.rs # gRPC server binary
├── roxid-tui/ # Terminal UI (gRPC client)
│ ├── Cargo.toml
│ ├── build.rs # Proto compilation
│ └── src/
│ ├── main.rs # Entry point
│ ├── app.rs # Application state and gRPC client
│ ├── events.rs # Event handling (keyboard, mouse)
│ └── ui/ # UI rendering modules
└── roxid-cli/ # CLI application (gRPC client)
├── Cargo.toml
├── build.rs # Proto compilation
└── src/
└── main.rs # CLI entry point with gRPC client
Architecture Layers
1. Pipeline Service (pipeline-service/)
- Purpose: gRPC service for pipeline execution
- Type: Library crate + binary executable
- Components:
- Library: Core pipeline execution engine and proto conversions
- Binary: gRPC server listening on port 50051
- Proto: Service definition with streaming execution events
- Features:
- Parse pipelines from files or strings
- Stream execution events in real-time
- Independent, language-agnostic service
- Structure:
models/: Data structures and domain modelspipeline/: Pipeline execution systemservices/: Business logic implementationserror.rs: Domain-specific error types
2. TUI Package (roxid-tui/)
- Purpose: Terminal user interface (gRPC client)
- Type: Binary crate (executable)
- Dependencies: gRPC client connecting to pipeline-service
- Structure:
main.rs: Application entry pointapp.rs: Application state and gRPC client managementevents.rs: User input handlingui/: UI rendering logic
3. CLI Package (roxid-cli/)
- Purpose: Command-line interface (gRPC client)
- Type: Binary crate (executable)
- Dependencies: gRPC client connecting to pipeline-service
- Structure:
main.rs: CLI entry point with gRPC client
Communication Architecture
┌─────────────┐ gRPC ┌──────────────────┐
│ roxid-tui │ ◄──────────────────► │ pipeline-service │
│ (client) │ Streaming Events │ (gRPC server) │
└─────────────┘ └──────────────────┘
▲
┌─────────────┐ gRPC │
│ roxid-cli │ ◄────────────────────────────┘
│ (client) │ Streaming Events
└─────────────┘
Key Architectural Benefits:
- Service Independence: Pipeline service runs independently, can be deployed remotely
- Language Agnostic: Any language with gRPC support can build clients
- Streaming: Real-time execution updates via gRPC streaming
- Scalability: Service can handle multiple concurrent clients
- Clean Separation: Clear boundary between service and clients
- Testability: Service and clients can be tested independently
gRPC Service Definition
The service provides two RPCs:
- ParsePipeline: Parse a pipeline from file path or string content
- ExecutePipeline: Execute a pipeline with streaming progress events
Events streamed during execution:
PipelineStarted: Pipeline execution beginsStepStarted: A step starts executingStepOutput: Real-time output from stepStepCompleted: Step finishes with resultPipelineCompleted: All steps complete
TUI Application Flow
-
Initialization:
- Connects to gRPC service on startup
- Discovers available pipeline YAML files via gRPC
-
Pipeline List State:
- Displays available pipeline YAML files
- User navigates with arrow keys and selects with Enter
-
Pipeline Execution State:
- Sends execute request to gRPC service
- Displays real-time progress bar (current step / total steps)
- Receives and displays streamed execution events
- Shows completion status (success/failure)
-
Event Loop: The main loop continuously:
- Draws the UI based on current state
- Handles keyboard events with non-blocking polling
- Processes incoming gRPC stream events
-
gRPC Communication:
- TUI maintains persistent connection to pipeline-service
- Uses gRPC streaming for real-time execution updates
- Automatically handles connection errors and retries
State Machine
┌─────────────────┐
│ PipelineList │
│ - Discover YAML │
│ - Navigate │
│ - Select │
└────────┬────────┘
│ Enter
▼
┌─────────────────┐
│ ExecutingPipe │
│ - Run pipeline │
│ - Show progress │
│ - Stream output │
└────────┬────────┘
│ Complete
▼
┌─────────────────┐
│ PipelineList │
│ (return) │
└─────────────────┘
Components
- App State Machine: Manages transitions between PipelineList and ExecutingPipeline states
- Event Handler: Non-blocking event processing with state-aware key bindings
- UI Rendering: Modular components for pipeline list, progress bar, and output display
- Pipeline Executor: Async execution with progress events streamed via channels
Pipeline System
Pipeline YAML Format
name: my-pipeline
description: Optional description
env:
GLOBAL_VAR: value
steps:
- name: Step name
command: echo "Hello World"
- name: Multi-line script
shell:
script: |
echo "Line 1"
echo "Line 2"
env:
STEP_VAR: value
continue_on_error: true
Creating a Pipeline
Create a file ending in .yaml or .yml:
name: my-first-pipeline
description: My first custom pipeline
steps:
- name: Hello World
command: echo "Hello from my pipeline!"
- name: Show Date
command: date
- name: List Files
command: ls -la
Basic Usage Example
use ;
use Result;
async
With Progress Reporting
use ;
// Create event channel
let = create_event_channel;
// Create handler and parse pipeline
let handler = new;
let pipeline = handler.parse_from_file?;
let working_dir = current_dir?.to_string_lossy.to_string;
// Spawn executor
let handle = spawn;
// Monitor progress
while let Some = rx.recv.await
let result = handle.await?;
Example Pipelines
Simple Test Pipeline
name: quick-test
steps:
- name: Check version
command: rustc --version
- name: Run tests
command: cargo test
Build Pipeline
name: build-pipeline
env:
RUST_BACKTRACE: "1"
steps:
- name: Format check
command: cargo fmt --check
continue_on_error: true
- name: Build
command: cargo build --all
- name: Test
command: cargo test --all
Pipeline Architecture
The pipeline system consists of:
- Parser (
pipeline/parser.rs) - Parses YAML into Rust structs - Executor (
pipeline/executor.rs) - Orchestrates step execution - Runners (
pipeline/runners/) - Execute different step typesshell.rs- Runs shell commands and scripts
- Models (
pipeline/models.rs) - Data structures for pipelines, steps, results
TUI Guide
Interface Overview
Pipeline List Screen
┌─────────────────────────────────────────────┐
│ Pipeline Runner │
└─────────────────────────────────────────────┘
┌─ Available Pipelines ──────────────────────┐
│ → example-pipeline - A simple example │
│ rust-build-pipeline - Build Rust project│
│ advanced-pipeline - Complex workflow │
└─────────────────────────────────────────────┘
┌─ Help ──────────────────────────────────────┐
│ ↑/↓: Navigate | Enter: Execute | q: Quit │
└─────────────────────────────────────────────┘
Pipeline Execution Screen
┌─────────────────────────────────────────────┐
│ Executing: example-pipeline │
└─────────────────────────────────────────────┘
┌─ Progress ──────────────────────────────────┐
│ ████████████░░░░░░░░ Step 3/5 │
└─────────────────────────────────────────────┘
┌─ Output ────────────────────────────────────┐
│ [Step 1/5] Check Rust version │
│ rustc 1.70.0 (90c541806 2023-05-31) │
│ ✓ Completed in 0.05s │
│ │
│ [Step 2/5] List files │
│ ✓ Completed in 0.02s │
│ │
│ [Step 3/5] Multi-line script │
│ Starting multi-line script │
└─────────────────────────────────────────────┘
Features:
- Real-time progress bar showing current step
- Live output streaming as commands execute
- Color-coded status indicators:
- ✓ Green for successful steps
- ✗ Red for failed steps
- Yellow for step headers
- Auto-scrolling output (shows most recent lines)
- Execution time per step
Execution Flow
- Select Pipeline: Use arrow keys to highlight a pipeline
- Start Execution: Press Enter to begin execution
- Watch Progress: View real-time progress and output
- Completion: Pipeline shows success or failure status
- Return to List: Press q or Esc to select another pipeline
Troubleshooting
No Pipelines Found
- Ensure you're in a directory with
.yamlor.ymlfiles - Check that files are valid pipeline YAML format
- Verify files have the required
nameandstepsfields
Pipeline Fails to Execute
- Check the output panel for error messages
- Verify commands are available on your system
- Check file permissions and working directory
- Review pipeline YAML syntax
TUI Doesn't Respond
- Ensure terminal supports TUI applications
- Check terminal size is adequate (minimum 80x24)
- Try resizing terminal window
Extending the Application
Adding a New Tab System
// Add to App struct:
// Handle tab switching:
Char => self.current_tab = Counter,
Char => self.current_tab = Items,
Char => self.current_tab = Settings,
Adding Scrolling to Lists
use ListState;
// Handle scrolling:
Up =>
Down =>
// Render with state:
frame.render_stateful_widget;
Adding Input Fields
// Handle input mode:
Char if !self.input_mode =>
Esc if self.input_mode =>
Char if self.input_mode =>
Backspace if self.input_mode =>
Enter if self.input_mode =>
Adding Mouse Support
use ;
// In handle_events:
Mouse => self.handle_mouse_event,
// Handler:
Adding Async Operations
// Add to Cargo.toml:
// tokio = { version = "1", features = ["full"] }
use mpsc;
use Duration;
async
Custom Pipeline Steps
To extend the pipeline system:
- Add new pipeline steps: Update pipeline YAML files with new commands or shell scripts
- Custom step runners: Implement new runners in
pipeline-service/src/pipeline/runners/ - RPC handlers: Add new RPC handlers in
pipeline-rpc/src/handlers/to expose new functionality - Update RPC API: Export new handlers and types in
pipeline-rpc/src/lib.rs - Client updates: Use new RPC handlers in CLI/TUI applications
- UI screens: Create new app states and corresponding UI components in TUI
- Pipeline filters: Add filtering/searching capabilities to the pipeline list
Remember: All client functionality must go through the RPC layer. Never import pipeline-service directly in CLI or TUI.
Best Practices
- Keep render functions pure - Don't modify state during rendering
- Handle errors gracefully - Use Result types and proper error handling
- Test rendering logic - Ratatui supports testing with Buffer
- Profile performance - TUI apps should render at 60fps
- Use proper terminal cleanup - Always restore terminal state on exit
Project Structure
Building and Running
# Build entire workspace
# Build specific package
# Start the gRPC service
# Run the TUI application (service must be running)
# Run the CLI application (service must be running)
# Run tests for all packages
# Run tests for specific package
# Check code without building
Benefits of This Architecture
- Service Independence: gRPC service can run anywhere, local or remote
- Language Agnostic: Clients can be written in any language with gRPC support
- Scalability: Service handles multiple concurrent clients
- Real-time Updates: Streaming gRPC provides live execution feedback
- Clean Separation: Service and clients are completely decoupled
- Testability: Each component can be tested independently
- Maintainability: Clear boundaries and standard protocols
- Extensibility: Easy to add new client types (web, mobile, etc.)
- Deployability: Service can be containerized and deployed independently
Resources
- Ratatui Documentation
- Ratatui Website
- Tonic gRPC Documentation
- Protocol Buffers
- Crossterm Documentation
License
This skeleton application is provided as-is for educational and development purposes.