Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rust Dependencies for pi-mono Feature Parity

Overview

This document maps the features from pi-mono’s TypeScript implementation to equivalent Rust crates for our TUI application.

Core TUI Framework

pi-mono: pi-tui (custom TypeScript)

Features:

  • Differential rendering (only updates changed lines)
  • Component-based architecture
  • Viewport management with scrollback
  • ANSI escape sequence safety
  • Overlay system for modals/popups

Rust Equivalent:

ratatui = "0.30"
crossterm = "0.29"  # Backend for ratatui

Notes:

  • ✅ ratatui has built-in differential rendering
  • ✅ Component system via Widget trait
  • ✅ Viewport management included
  • ✅ ANSI safety handled by crossterm

Text Editor / Input

pi-mono: Custom editor in pi-tui

Features:

  • Multi-line text input
  • Cursor movement
  • Syntax highlighting integration
  • Vim-style or Emacs keybindings
  • Text selection

Rust Options:

Option 1: Basic input (built-in)

ratatui = "0.30"  # Has TextArea widget

Option 2: Enhanced editor

# Vim-like editor
edtui = "0.11"
# OR
tui-textarea = "0.4"
# OR
ratatui-code-editor = "0.0.1"  # Tree-sitter powered

Recommendation: Start with ratatui’s built-in TextArea, upgrade to edtui or ratatui-code-editor if we need vim bindings or advanced editing.


Markdown Rendering

pi-mono: marked (TypeScript library)

Features:

  • Parse markdown to styled terminal output
  • Support for headings, lists, code blocks, links
  • Custom rendering for AI responses

Rust Equivalent:

tui-markdown = "0.3"
pulldown-cmark = "0.13"  # Underlying parser

Alternative (more comprehensive):

md-tui = "0.9"  # Full markdown viewer with navigation

Notes:

  • tui-markdown converts markdown to ratatui Text values
  • Supports all standard markdown features
  • Can customize styling for AI output

Syntax Highlighting

pi-mono: Custom integration with highlighting

Features:

  • Code block syntax highlighting
  • Multiple language support
  • Theme support

Rust Equivalent:

syntect = "5.3"        # Core syntax highlighting
syntect-tui = "3.0"    # Bridge to ratatui styles

Alternative (tree-sitter based):

tui-syntax = "0.4"     # Tree-sitter based
tree-sitter = "0.24"   # Parser framework

Notes:

  • syntect uses Sublime Text syntax definitions (high quality)
  • 100+ languages supported out of the box
  • syntect-tui converts syntect styles to ratatui Styles

File Tree / Navigation

pi-mono: Tree selector for sessions and files

Features:

  • Hierarchical tree view
  • Collapsible/expandable nodes
  • Keyboard navigation
  • File icons/indicators

Rust Equivalent:

tui-tree-widget = "0.24"
# OR
ratatui-explorer = "0.2"

Notes:

  • tui-tree-widget: Pure tree widget for any tree data
  • ratatui-explorer: File explorer specifically (like ranger)

Diff Viewing

pi-mono: File diff display for code changes

Features:

  • Side-by-side or unified diff
  • Syntax highlighting in diffs
  • Color-coded additions/deletions
  • Line numbers

Rust Equivalent:

# Option 1: Use syntect with custom diff logic
syntect = "5.3"

# Option 2: Leverage delta (pager)
# Shell out to delta or integrate as library

Implementation approach:

#![allow(unused)]
fn main() {
// Parse diff output
// Use syntect to highlight each line
// Apply ratatui styles for additions (green) / deletions (red)
}

Clipboard Integration

pi-mono: Clipboard access for copy/paste

Features:

  • Copy text to system clipboard
  • Paste from clipboard
  • Cross-platform support

Rust Equivalent:

arboard = "3.6"

Notes:

  • Cross-platform (Linux X11/Wayland, macOS, Windows)
  • Supports both text and images
  • 1Password maintains this crate (high quality)

Async / Streaming

pi-mono: Event-driven with async/await

Features:

  • Handle multiple async events
  • Stream LLM responses
  • Non-blocking UI updates
  • Event queue/channels

Rust Equivalent:

tokio = { version = "1", features = ["full"] }
tokio-stream = "0.1"
futures = "0.3"
async-trait = "0.1"

Pattern:

#![allow(unused)]
fn main() {
// Event loop with tokio
let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel();

// Spawn async task for events
tokio::spawn(async move {
    while let Some(event) = rx.recv().await {
        // Handle event
    }
});
}

Configuration Management

pi-mono: YAML/JSON config files

Features:

  • User config in ~/.config/pi/
  • Project-level config
  • Environment variable overrides
  • Theme configuration

Rust Equivalent:

config = "0.15"        # Layered config (file, env, etc.)
toml = "0.9"           # TOML parsing
serde = { version = "1.0", features = ["derive"] }
directories = "5"      # XDG dirs (cross-platform)

Alternative (more powerful):

figment = "0.10"       # Used by Rocket, very flexible

Notes:

  • config crate: Supports TOML, YAML, JSON, INI
  • directories: Gets platform-appropriate config dirs
  • XDG on Linux, ~/Library/Application Support on macOS, %APPDATA% on Windows

HTTP / LLM API

pi-mono: pi-ai (unified LLM API)

Features:

  • Multiple provider support (OpenAI, Anthropic, etc.)
  • Streaming responses
  • Retry logic
  • Authentication

Rust Equivalent:

reqwest = { version = "0.12", features = ["json", "stream"] }
tokio = "1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

For specific providers:

async-openai = "0.26"  # If using OpenAI specifically

Custom trait approach (recommended):

#![allow(unused)]
fn main() {
#[async_trait]
trait LlmProvider {
    async fn complete(&self, request: Request) -> Result<Response>;
    async fn stream(&self, request: Request) -> Result<Stream<Item=Token>>;
}
}

Themes

pi-mono: Theme system with JSON themes

Features:

  • Custom color schemes
  • User-defined themes
  • Syntax highlighting themes
  • Terminal color detection

Rust Equivalent:

ratatui = "0.30"  # Has Style system
syntect = "5.3"   # Has theme support for syntax

For theme loading:

serde = { version = "1.0", features = ["derive"] }
toml = "0.9"      # Or json, yaml

Implementation:

#![allow(unused)]
fn main() {
#[derive(Deserialize)]
struct Theme {
    background: Color,
    foreground: Color,
    accent: Color,
    // ...
}
}

Key Bindings / Input

pi-mono: Custom keyboard protocol

Features:

  • Vim-style keybindings
  • Command palette (/ commands)
  • Configurable shortcuts
  • Key sequences (chords)

Rust Equivalent:

crossterm = "0.29"  # Has key event handling

For complex keybindings:

#![allow(unused)]
fn main() {
// crossterm provides KeyEvent, KeyCode, KeyModifiers
// Build a keymap system on top

enum Action {
    SendMessage,
    NewConversation,
    Quit,
    // ...
}

struct KeyMap {
    bindings: HashMap<(KeyCode, KeyModifiers), Action>,
}
}

State Management

pi-mono: Agent state management

Features:

  • Conversation history
  • Context management
  • Tool state
  • Session persistence

Rust Equivalent:

# In-memory: Standard Rust
# Persistence:
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

# Database (optional):
sqlx = { version = "0.8", features = ["runtime-tokio", "sqlite"] }
# OR for simpler use:
redb = "2.0"  # Pure Rust embedded DB

Complete Cargo.toml

[package]
name = "harness-tui"
version = "0.1.0"
edition = "2021"

[dependencies]
# Core TUI
ratatui = { version = "0.30", features = ["crossterm"] }
crossterm = "0.29"

# Editor
edtui = "0.11"  # Optional: for vim bindings

# Markdown
tui-markdown = "0.3"
pulldown-cmark = "0.13"

# Syntax highlighting
syntect = "5.3"
syntect-tui = "3.0"

# File tree
tui-tree-widget = "0.24"

# Clipboard
arboard = "3.6"

# Async
tokio = { version = "1", features = ["full"] }
tokio-stream = "0.1"
futures = "0.3"
async-trait = "0.1"

# HTTP
reqwest = { version = "0.12", features = ["json", "stream", "rustls-tls"] }

# Config
config = "0.15"
toml = "0.9"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
directories = "5"

# Persistence (optional)
redb = "2.0"

# Error handling
color-eyre = "0.6"  # Better error reporting
thiserror = "1.0"

# Logging
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

# CLI
clap = { version = "4.5", features = ["derive"] }

# Utilities
unicode-width = "0.2"
textwrap = "0.16"
chrono = { version = "0.4", features = ["serde"] }

[dev-dependencies]
tokio-test = "0.4"

Feature Comparison Summary

Featurepi-monorobit (Rust)
TUI FrameworkCustom pi-tuiratatui
Differential Rendering✅ Custom✅ Built-in
Text EditorCustomedtui / ratatui-code-editor
Markdownmarkedtui-markdown
Syntax HighlightingCustomsyntect + syntect-tui
File TreeCustomtui-tree-widget
Diff ViewingCustomsyntect + custom
ClipboardNativearboard
AsyncNode.js asynctokio
ConfigYAML/JSONtoml + config
HTTPNode fetchreqwest
ThemesJSONtoml + serde
StateIn-memoryredb / sqlite

Advantages of Rust Stack

  1. Type Safety: Compile-time guarantees for all UI state
  2. Performance: Zero-cost abstractions, no GC pauses
  3. Single Binary: No Node.js runtime dependency
  4. Memory Safety: No null pointer exceptions or undefined behavior
  5. Ecosystem: Cross-platform native performance

Development Workflow

# Add dependencies
cargo add ratatui crossterm tokio serde reqwest

# Development
cargo run          # Run TUI
cargo test         # Run tests
cargo clippy       # Lint
cargo build --release  # Optimized build

# Single binary output: target/release/harness-tui

No npm install. No node_modules. No webpack.

Just Rust.