Skip to content

TUI framework and developer productivity apps in Rust 🦀

License

r3bl-org/r3bl-open-core

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

r3bl-open-core

██████╗ ██████╗ ██████╗ ██╗         ████████╗██╗   ██╗██╗
██╔══██╗╚════██╗██╔══██╗██║         ╚══██╔══╝██║   ██║██║
██████╔╝ █████╔╝██████╔╝██║            ██║   ██║   ██║██║
██╔══██╗ ╚═══██╗██╔══██╗██║            ██║   ██║   ██║██║
██║  ██║██████╔╝██████╔╝███████╗       ██║   ╚██████╔╝██║
╚═╝  ╚═╝╚═════╝ ╚═════╝ ╚══════╝       ╚═╝    ╚═════╝ ╚═╝

Table of contents:

Why R3BL TUI?

After leaving Google in 2021, I (Nazmul Idris) embarked on creating infrastructure for modern, powerful CLI and TUI experiences built from the ground up in Rust.

The core architectural innovation: a purely async, immediate mode reactive UI (every state change triggers a render from scratch) where nothing blocks the main thread - unlike traditional approaches using platform-specific blocking operations like POSIX readline() on Linux/macOS or Windows ReadConsole().

R3BL TUI is fundamentally different from vim, neovim, and ratatui through its immediate mode reactive UI with clean separation between rendering and state mutation, and purely async nature.

This fully async, responsive framework works seamlessly across Linux, macOS, and Windows. It's optimized for use over SSH connections by painting only diffs, and handles complex concurrent operations with low latency while ensuring no thread blocking.

The Problem with Existing Solutions

I initially tried Node.js with ink, but encountered fundamental limitations:

  • Module incompatibilities and dependency conflicts
  • Limited control over keybindings and terminal behavior
  • High resource consumption for simple tasks
  • Screen flickering and poor rendering performance

The R3BL Solution: Web and Desktop App Inspired Terminal Apps

Our framework supports the full spectrum from CLI to hybrid TUI to full TUI experiences with deep system integration.

Key Innovation: "Applets" - A revolutionary state management system that allows processes to persist state across their lifecycle and share it with other instances or processes.

Built-from-Scratch Primitives

Async Readline: Unlike POSIX readline which is single-threaded and blocking, our implementation is fully async, interruptable, and non-blocking.

Choose API: Single-shot user interactions that enter raw mode without taking over the screen or disrupting the terminal's back buffer.

Full TUI: Complete raw mode with alternate screen support, fully async and non-destructive.

All components are end-to-end testable using our InputDevice and OutputDevice abstractions for stdin, stdout, and stderr.

Advanced Rendering & Styling

  • CSS-like styling with JSX-inspired declarative layouts
  • Gradient color support with automatic terminal capability detection
  • Double-buffered compositor for efficient rendering
  • Comprehensive color support that adapts to terminal capabilities (even handles macOS Terminal.app's lack of truecolor support)

Rich Component Ecosystem

  • Beautiful Markdown parser with syntax highlighting
  • Rich text editor components
  • Dialog box support
  • Animation framework (in development)
  • Process orchestration via the "script" module
  • Async REPL infrastructure

R3BL TUI brings the power and ergonomics of modern web development to the terminal, creating a new paradigm for command-line productivity tools.

We are working on building command line apps in Rust which have rich text user interfaces (TUI). We want to lean into the terminal as a place of productivity, and build all kinds of awesome apps for it.

  1. 🔮 Instead of just building one app, we are building a library to enable any kind of rich TUI development w/ a twist: taking concepts that work really well for the frontend mobile and web development world and re-imagining them for TUI & Rust.
  • Taking inspiration from things like React, SolidJS, Elm, iced-rs, Jetpack Compose, JSX, CSS, but making everything async (so they can be run in parallel & concurrent via Tokio).
  • Even the thread running the main event loop doesn't block since it is async.
  • Using macros to create DSLs to implement something inspired by CSS & JSX.
  1. 🌎 We are building apps to enhance developer productivity & workflows.
  • The idea here is not to rebuild tmux in Rust (separate processes mux'd onto a single terminal window). Rather it is to build a set of integrated "apps" (or "tasks") that run in the same process that renders to one terminal window.
  • Inside of this terminal window, we can implement things like "applet" switching, routing, tiling layout, stacking layout, etc. so that we can manage a lot of TUI apps (which are tightly integrated) that are running in the same process, in the same window. So you can imagine that all these "applets" have shared application state. Each "applet" may also have its own local application state.
  • You can mix and match "Full TUI" with "Partial TUI" to build for whatever use case you need. r3bl_tui allows you to create application state that can be moved between various "applets", where each "applet" can be "Full TUI" or "Partial TUI".
  • Here are some examples of the types of "app"s we plan to build (for which this infrastructure acts as the open source engine):
    1. Multi user text editors w/ syntax highlighting.
    2. Integrations w/ github issues.
    3. Integrations w/ calendar, email, contacts APIs.

Welcome to the monorepo and workspace

All the crates in the r3bl-open-core monorepo provide lots of useful functionality to help you build TUI (text user interface) apps, along w/ general niceties & ergonomics that all Rustaceans 🦀 can enjoy 🎉.

Any top-level folder in this repository that contains a Cargo.toml file is a Rust project, also known as a crate. These crates are likely published to crates.io. Together, they form a Rust workspace.

Here's the changelog for this monorepo containing a Rust workspace. The changelog is a great place to start to get familiar with what has changed recently in each of the crates in this Rust workspace.

This workspace contains crates for building TUI, CLI, TTY apps

The r3bl_tui crate is the main crate that contains the core functionality for building TUI apps. It allows you to build apps that range from "full" TUI to "partial" TUI, and everything in the middle.

Here are some videos that you can watch to get a better understanding of TTY programming.

Full TUI (async, raw mode, full screen) for immersive TUI apps

tui gives you "raw mode", "alternate screen" and "full screen" support, while being totally async. An example of this is the "Full TUI" app edi in the r3bl-cmdr crate. You can install & run this with the following command:

cargo install r3bl-cmdr
edi

Partial TUI (async, partial raw mode, async readline) for choice based user interaction

choose allows you to build less interactive apps that ask a user user to make choices from a list of options and then use a decision tree to perform actions.

An example of this is this "Partial TUI" app giti in the r3bl-cmdr crate. You can install & run this with the following command:

cargo install r3bl-cmdr
giti

Partial TUI (async, partial raw mode, async readline) for async REPL

readline_async gives you the ability to easily ask for user input in a line editor. You can customize the prompt, and other behaviors, like input history.

Using this, you can build your own async shell programs using "async readline & stdout". Use advanced features like showing indeterminate progress spinners, and even write to stdout in an async manner, without clobbering the prompt / async readline, or the spinner. When the spinner is active, it pauses output to stdout, and resumes it when the spinner is stopped.

An example of this is this "Partial TUI" app giti in the r3bl-cmdr crate. You can install & run this with the following command:

cargo install r3bl-cmdr
giti

Here are other examples of this:

  1. https://github.com/nazmulidris/rust-scratch/tree/main/tcp-api-server
  2. https://github.com/r3bl-org/r3bl-open-core/tree/main/tui/examples

Power via composition

You can mix and match "Full TUI" with "Partial TUI" to build for whatever use case you need. r3bl_tui allows you to create application state that can be moved between various "applets", where each "applet" can be "Full TUI" or "Partial TUI".

Main library crate

There is just one main library crate in this workspace: r3bl_tui.

Main binary crate

There is just one main binary crate that contains user facing apps that are built using the library crates: r3bl-cmdr. This crate contains these apps:

  • giti: Interactive git workflows made easy.
  • edi: Beautiful Markdown editor with advanced rendering and editing features.

You can install & run this with the following command:

cargo install r3bl-cmdr
# Interactive git workflows made easy.
giti --version
# Beautiful Markdown editor with advanced rendering and editing features.
edi --version

Project Task Organization

This project uses three root-level Markdown files to organize day-to-day development work:

Task Management Files

  • todo.md - Active tasks and immediate priorities that need attention
  • done.md - Completed tasks and achievements, providing a historical record of progress
  • claude.md - AI assistant interaction logs and collaborative planning sessions

Workflow Connection

The task organization workflow connects with the documentation in docs/ as follows:

  • Strategic to Tactical: Items from docs/ planning files (strategic goals, feature designs) are broken down into actionable tasks and copied into todo.md
  • Planning to Execution: Complex features get documented in docs/ first, then their implementation steps flow into the daily task management system
  • Documentation of Decisions: AI-assisted development sessions and decision-making processes are logged in claude.md for future reference

This dual-level approach ensures both strategic planning (in docs/) and tactical execution (in root-level .md files) are well-organized and connected.

Documentation and Planning

The docs/ folder contains comprehensive documentation for this project, including:

Release and Contribution Guides

  • release-guide.md - Step-by-step guide for releasing new versions
  • contributing_guides/ - Detailed contribution guidelines including:
    • Branch naming conventions (BRANCH.md)
    • Commit message standards (COMMIT_MESSAGE.md)
    • Issue creation guidelines (ISSUE.md)
    • Pull request procedures (PULL_REQUEST.md)
    • Code style guide (STYLE_GUIDE.md)

Technical Design Documents

  • Parser strategy analysis and design decisions
  • Performance optimization guides (docs/task_tui_perf_optimize.md)
  • Architecture documentation for various components
  • Feature-specific planning and design documents

The docs/ folder serves as the central repository for:

  • Long-term planning: Strategic goals and feature roadmaps
  • Technical decisions: Architecture choices and implementation strategies
  • Process documentation: How we work and contribute to the project
  • Design artifacts: Detailed analysis of complex features before implementation

Learn how these crates are built, provide feedback

To learn how we built this crate, please take a look at the following resources.

Quick Start

Automated Setup (Recommended)

For Linux and macOS users, use the bootstrap script to automatically install all required tools:

# Clone the repository
git clone https://github.com/r3bl-org/r3bl-open-core.git
cd r3bl-open-core

# Run the bootstrap script
./bootstrap.sh

The bootstrap.sh script handles OS-level setup with a clean main function structure and will:

  • System Package Manager Detection: Automatically detects apt, dnf, pacman, zypper, or brew
  • Core Rust Installation: Install Rust toolchain (rustup) and ensure cargo is in PATH
  • Compiler Setup: Install clang compiler (required by Wild linker)
  • Development Shell: Install Fish shell and fzf for interactive development
  • File Watching: Install file watchers (inotifywait on Linux, fswatch on macOS)
  • Development Utilities: Install htop, screen, tmux for system monitoring
  • Node.js Ecosystem: Install Node.js and npm for web tooling
  • AI Integration: Install Claude Code CLI with MCP server configuration
  • Rust Development Tools Setup: Call fish run.fish install-cargo-tools for all Rust-specific tooling

Architecture: Uses clear function separation with main() orchestrator and dedicated functions for each concern (install_rustup, install_clang, install_shell_tools, etc.)

Manual Setup

If you prefer manual installation or are on Windows:

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install Fish and fzf (via package manager)
# Ubuntu/Debian: sudo apt install fish fzf
# macOS: brew install fish fzf
# Or run ./bootstrap.sh for automatic detection

# Install Rust development tools (after OS dependencies)
fish run.fish install-cargo-tools

Note: The manual approach requires you to install OS-level dependencies yourself. The install-cargo-tools command focuses specifically on Rust development tools:

  • cargo-binstall: Fast binary installer (installed first as foundation)
  • uv: Modern Python package manager (required for Serena semantic code MCP server)
  • Core Development Tools: bacon, flamegraph, inferno
  • Workspace Management: cargo-workspaces, cargo-cache, cargo-update
  • Code Quality: cargo-deny, cargo-unmaintained, cargo-expand, cargo-readme
  • Wild Linker: Fast linker with optimized .cargo/config.toml generation
  • Language Server: rust-analyzer component
  • Smart Installation: Uses cargo-binstall for speed with fallback to cargo install --locked
  • Shared Utilities: Leverages utility functions from script_lib.fish for consistency

IDE Setup and Extensions

R3BL VSCode Extensions

For an optimal development experience with r3bl-open-core, we provide a custom VSCode extension pack specifically designed for Rust development. This extension pack is not available on the VSCode marketplace and must be installed manually.

What's included:

  • R3BL Theme - A carefully crafted dark theme optimized for Rust and Markdown development
  • Auto Insert Copyright - Automatically inserts copyright headers in new files
  • Semantic Configuration - Enhanced Rust syntax highlighting with additional semantic tokens
  • Extension Pack - Bundles all R3BL extensions for easy installation

Benefits for r3bl-open-core development:

  • Zero manual configuration required
  • Enhanced semantic highlighting for better code readability
  • Automatic copyright header insertion following project standards
  • Seamless integration with rust-analyzer
  • Optimized color scheme for the r3bl codebase

Installation:

# Clone the extension repository
git clone https://github.com/r3bl-org/r3bl-vscode-extensions.git
cd r3bl-vscode-extensions

# Install extensions (works with both VSCode and VSCode Insiders)
./install.sh

Prerequisites:

  • VSCode or VSCode Insiders installed
  • Bash shell (for running install.sh)

Post-installation:

  1. Restart VSCode
  2. Select the R3BL Theme: Ctrl+Shift+P → "Preferences: Color Theme" → "R3BL Theme"
  3. Configure copyright settings if needed

The extensions work seamlessly with the existing development tools mentioned in this guide, including rust-analyzer and bacon.

Build the workspace and run tests

There's a unified fish script that you can use to run the build and release pipeline for this workspace, and more (local only operations).

To get a list of available commands, you can review the fish script in the root of this repo run.fish. To see all available commands:

fish run.fish

You should see output that looks like this:

Usage: fish run.fish <command> [args]

Workspace-wide commands:
    all                  Run all major checks
    build                Build entire workspace
    build-full           Full build with clean and update
    clean                Clean entire workspace
    test                 Test entire workspace
    check                Check all workspaces
    clippy               Run clippy on all workspaces
    clippy-pedantic      Run clippy with pedantic lints
    docs                 Generate docs for all
    serve-docs           Serve documentation
    rustfmt              Format all code
    install-cargo-tools  Install Rust development tools
    upgrade-deps         Upgrade dependencies
    audit-deps           Security audit
    unmaintained         Check for unmaintained deps
    build-server         Remote build server - uses rsync

Watch commands:
    watch-all-tests      Watch files, run all tests
    watch-one-test [pattern]  Watch files, run specific test
    watch-clippy         Watch files, run clippy
    watch-check          Watch files, run cargo check

TUI-specific commands:
    run-examples [--release] [--no-log]  Run TUI examples
    run-examples-flamegraph-svg  Generate SVG flamegraph
    run-examples-flamegraph-fold [--benchmark]  Generate perf-folded format (use --benchmark for reproducible profiling)
    bench                Run benchmarks

cmdr-specific commands:
    run-binaries         Run edi, giti, or rc
    install-cmdr         Install cmdr binaries
    docker-build         Build release in Docker

Other commands:
    log                  Monitor log.txt in cmdr or tui directory
    help                 Show this help

Key Commands

Command Description
fish run.fish all Run all major checks (build, test, clippy, docs, audit, format)
fish run.fish build Build the entire workspace
fish run.fish test Run all tests across the workspace
fish run.fish install-cargo-tools Install Rust development tools (cargo-binstall, uv, bacon, Wild linker, etc.)
fish run.fish watch-all-tests Watch for file changes and run tests automatically
fish run.fish run-examples Run TUI examples interactively
fish run.fish run-examples-flamegraph-svg Generate SVG flamegraph for performance analysis
fish run.fish run-examples-flamegraph-fold [--benchmark] Generate perf-folded format for analysis (use --benchmark for reproducible profiling)
fish run.fish bench Run benchmarks
fish run.fish run-binaries Run cmdr binaries (edi, giti, rc) interactively
fish run.fish dev-dashboard Start 4-pane tmux development dashboard (tests, docs, checks)
fish run.fish check-full Run comprehensive checks (tests, doctests, docs, toolchain validation)
fish run.fish toolchain-validate Quick toolchain validation (components only, ~1-2 seconds)
fish run.fish toolchain-validate-complete Complete toolchain validation (full build+test, ~5-10 minutes)
fish run.fish toolchain-update Update Rust to month-old nightly toolchain with cleanup
fish run.fish toolchain-sync Sync Rust environment to match rust-toolchain.toml
fish run.fish toolchain-remove Remove ALL toolchains (⚠️ destructive testing utility)

Cargo Target Directory Isolation for IDE/Tool Performance

Critical Optimization: When multiple development tools run cargo simultaneously (IDE, terminal, file watcher, CI), they compete for locks on the shared target/ directory. This causes severe responsiveness issues as each tool waits for others to complete. Isolating build artifacts by tool eliminates this bottleneck completely.

The Problem: Cargo Lock Contention

When you have multiple cargo instances running:

  • VSCode rust-analyzer: Runs cargo check continuously in background
  • RustRover: Runs cargo check continuously in background
  • File watcher (check.fish, bacon): Triggers cargo tests, doc builds, etc. on every file save
  • Terminal: You run manual cargo commands, and Claude Code is running commands

All these access the same target/ directory:

target/
├── debug/
├── release/
└── .rustc_info.json  # ← Lock contention here

When one tool locks target/, all others wait. This cascades into a "traffic jam" where everything becomes unresponsive.

The Solution: Separate Build Artifacts

Configure each tool to use its own target directory. Rust supports this via the CARGO_TARGET_DIR environment variable:

target/
├── vscode/      # VSCode rust-analyzer builds
├── rustrover/   # JetBrains IDE builds
├── claude/      # Claude Code builds
├── check/       # check.fish file watcher builds
└── cli/         # Terminal manual builds (optional)

Now tools build in parallel without interfering with each other.

Configuration by Tool

Generally speaking you can just add CARGO_TARGET_DIR=target/XYZ in the command, for eg you can run the following in your terminal to run claude with the CARGO_TARGET_DIR env var set, and all the cargo commands spawned by claude will have their own taret directory to work with:

CARGO_TARGET_DIR=target/claude $argv

You can add this to an alias, add it to scripts (like check.fish does via set -gx CARGO_TARGET_DIR target/check) or you can configure settings in your tool of choice.

In VSCode, you can add the following to .vscode/settings.json:

{
  "rust-analyzer.cargo.targetDir": true
}

In RustRover, you can go to "Settings -> Rust -> Environment Variables" and add this CARGO_TARGET_DIR=target/rustrover

Benefits

Benefit Impact
Zero Contention Tools run in parallel without waiting on locks
Responsive IDE rust-analyzer completes checks while you code (not blocked by file watcher)
Faster Feedback Terminal cargo commands complete instantly (not queued behind IDE checks)
Parallel Testing bacon + check.fish both run, providing redundant test feedback
Disk Space ~2-3GB per tool (manageable with cleanup)

Example Workflow Setup

Here's a typical productive development workflow setup:

# Terminal 1: Running your IDE (VSCode with rust-analyzer)
CARGO_TARGET_DIR=target/vscode code .

# Terminal 2: File watcher with automatic tests
check.fish --watch-tests # Runs with: CARGO_TARGET_DIR=target/check

# Terminal 3: Run claude code
CARGO_TARGET_DIR=target/claude claude

# Terminal 4: Run bacon
CARGO_TARGET_DIR=target/bacon bacon doc --headless

# Result: All three run in parallel, zero blocking

Before this optimization, Terminal 3 would hang waiting for Terminals 1-2 to release the target/ lock.

Disk Space Management

Each tool caches ~2-3GB of build artifacts. With 4 tools, expect ~10-12GB total. To manage:

# View size of each target directory
du -sh target/*/

# Clean individual tool builds
rm -rf target/vscode
rm -rf target/rustrover
rm -rf target/claude
rm -rf target/check

# Full cleanup (nuclear option)
rm -rf target/

Troubleshooting

Syntax errors still appear in IDE but code works in terminal?

Your IDE and terminal are using different target directories. Verify CARGO_TARGET_DIR configuration:

# Check what each tool sees
echo $CARGO_TARGET_DIR  # Terminal value
# VSCode: Check .vscode/settings.json
# RustRover: Check IDE settings

Build artifacts aren't being reused across tools?

Each tool has its own target/ directory by design. This is correct - the slight disk space overhead is worth the responsiveness gain. If you need to share builds, unset CARGO_TARGET_DIR (not recommended for development).

"Target directory not found" error?

Cargo automatically creates the directory. If you see this error, verify the path is writable and the environment variable is set correctly:

# Verify the variable is actually set
env | grep CARGO_TARGET_DIR

# Test with explicit path
CARGO_TARGET_DIR=/tmp/test cargo build

Incremental Compilation Management

Incremental compilation is disabled globally (incremental = false in .cargo/config.toml) to avoid issues with the rustc dependency graph on nightly builds:

# .cargo/config.toml
[build]
incremental = false  # Disable to avoid rustc dep graph ICE on nightly

Why disable incremental compilation?

  • The nightly compiler has occasional bugs with the dependency graph in incremental mode
  • These bugs can cause Internal Compiler Errors (ICE) like "mir_drops_elaborated_and_const_checked"
  • Disabling it globally ensures stable builds across all cargo invocations
  • The performance impact is acceptable for development workflows

If you encounter ICE errors anyway:

# Clear any corrupted incremental artifacts
rm -rf target/check target/debug target/release

# Rebuild cleanly
cargo check  # or cargo build, cargo test, etc.

The check.fish script also explicitly sets CARGO_INCREMENTAL=0 as a redundant safeguard.

Bacon Development Tools

This project includes bacon configuration for background code checking and testing. Bacon provides real-time feedback on code changes with two distinct workflows:

Interactive Workflow (Rich TUI with details):

  • Full terminal UI with detailed output
  • Ctrl+click on errors and warnings to jump directly to source code (via OSC hyperlinks)
  • Perfect for active debugging and development

Background Workflow (Silent monitoring):

  • Minimal output - just success/failure status
  • Answers simple yes/no questions like "do tests pass?" or "do docs build?"
  • Ideal for background monitoring while focusing on other tasks

Available Bacon Commands:

Code Quality & Checking:

Command Description
bacon check Fast typecheck of default target
bacon check-all Typecheck all targets (lib, bins, tests, benches, examples)
bacon clippy Run clippy lints on default target
bacon clippy-all Run clippy lints on all targets (keybinding: c)

Testing:

Command Workflow Description
bacon test Interactive Run all tests with cargo test (includes unit, integration, and doctests)
bacon test -- <pattern> Interactive Run specific test matching pattern
bacon doctests Interactive Run only documentation tests (cargo test --doc)
bacon test --headless --summary Background Silent test runner providing only pass/fail status

Documentation:

Command Workflow Description
bacon doc Interactive Generate documentation with detailed output
bacon doc --headless --summary Background Silent doc builder answering "did docs generate?"
bacon doc-open Interactive Generate docs and open in browser

Running & Benchmarking:

Command Description
bacon run Build and run the project in background
bacon run-long Run long-running processes (e.g., servers) with auto-restart on changes
bacon ex -- <example_name> Run specific example (e.g., bacon ex -- my-example)
bacon bench Run performance benchmarks

Choose the workflow that matches your current needs:

  • Use interactive when actively debugging or wanting detailed feedback
  • Use background for continuous monitoring, CI/CD pipelines, or when you just need to know if things work

Testing Notes:

  • Use bacon test to run all tests (includes unit, integration, and doctests)
  • Use bacon doctests or bacon test --doc to run only documentation tests

Automated Development Monitoring

The project provides two complementary approaches for continuous monitoring during development - choose based on your workflow preferences:

Option 1: Lightweight Watch Mode (Recommended for Most Users)

For developers who want automated monitoring without the overhead of tmux, use the standalone check script:

./check.fish --watch

What it does:

  • Monitors source directories: Watches cmdr/src/, analytics_schema/src/, and tui/src/ for changes
  • Event-driven execution: Triggers immediately on file changes (no polling delay)
  • Intelligent debouncing: 5-second delay prevents rapid re-runs during saves
  • Comprehensive checks: Runs tests, doctests, and doc builds automatically
  • Clean progress output: Shows stage-by-stage progress without verbose cargo logs
  • Automatic toolchain validation: Validates and repairs Rust toolchain before checks
  • ICE recovery: Detects and recovers from Internal Compiler Errors automatically
  • Continuous operation: Keeps watching even if checks fail (perfect for iterative development)

Example output:

👀 Watch mode activated
Monitoring: cmdr/src, analytics_schema/src, tui/src
Press Ctrl+C to stop

🔄 Changes detected, running checks...

▶️  Running tests...
✅ Tests passed

▶️  Running doctests...
✅ Doctests passed

▶️  Building docs...
✅ Docs built

✅ All checks passed!

👀 Watching for changes...

Benefits:

  • Single window: No tmux complexity - just one terminal
  • Immediate feedback: 2-second response time after file saves
  • Low overhead: Minimal resource usage compared to running multiple monitors
  • Perfect for focus: Clean output doesn't distract from your editor

Event handling: While checks run (30+ seconds), the Linux kernel buffers new file change events. When checks complete, buffered events trigger immediately if debounce allows. This ensures no changes are lost but may cause cascading re-runs if you save multiple times during test execution. Adjust DEBOUNCE_SECONDS in the script if needed.

Usage:

# Show available options
./check.fish --help

# Start watch mode
./check.fish --watch

# Or run checks once (manual mode)
./check.fish

Option 2: Comprehensive Tmux Dashboard

Tmux Development Dashboard

For developers who prefer a multi-pane visual environment, the tmux dashboard combines multiple bacon monitors with the check.fish --watch script for comprehensive coverage.

When to choose tmux dashboard over standalone watch mode:

  • You want to see all checks running simultaneously in different panes
  • You prefer visual separation between tests, doctests, docs, and comprehensive checks
  • You're comfortable with tmux keybindings and pane navigation
  • You have screen space for a 2x2 grid layout

Comprehensive 4-Pane Development Dashboard:

┌─────────────────────────────────────────────────────────────┐
│ Tmux Session: r3bl-dev (2x2 grid layout)                    │
├──────────────────────┬──────────────────────────────────────┤
│ Top-left:            │ Top-right:                           │
│ bacon test           │ bacon doc                            │
│ (Unit & Integration  │ (Documentation generation            │
│  Tests)              │  with live feedback)                 │
├──────────────────────┼──────────────────────────────────────┤
│ Bottom-left:         │ Bottom-right:                        │
│ bacon doctests       │ ./check.fish --watch                 │
│ (Documentation       │ (Event-driven comprehensive checks:  │
│  Tests)              │  tests + doctests + docs + ICE)      │
└──────────────────────┴──────────────────────────────────────┘

Key Features:

  • Persistent Session: Session name "r3bl-dev" - reconnect from other terminals with tmux attach-session -t r3bl-dev
  • Multiple Monitors: Combines three bacon monitors (tests, doctests, docs) with one comprehensive check monitor (check.fish --watch)
  • Event-Driven Checks: The bottom-right pane runs ./check.fish --watch which triggers immediately on file changes (not periodic polling)
  • Comprehensive Coverage: The check.fish --watch monitor provides:
    • All unit and integration tests (cargo test --all-targets)
    • Documentation tests (cargo test --doc)
    • Documentation building (cargo doc --no-deps)
    • Automatic ICE (Internal Compiler Error) detection and recovery
    • Automatic toolchain validation and repair if needed
    • 5-second intelligent debouncing to prevent rapid re-runs
  • Interactive Multiplexing: Full tmux keybindings for pane switching and layout customization
  • Redundant Coverage: Tests run in two panes (bacon test + check.fish) - if one fails, the other shows details

Usage:

# Start the development dashboard
fish run.fish dev-dashboard

# Reconnect to existing session from another terminal
tmux attach-session -t r3bl-dev

# Kill the session when done
tmux kill-session -t r3bl-dev

Comparison: Standalone vs Tmux Dashboard:

Aspect ./check.fish --watch Tmux Dashboard
Setup Complexity Single command, one window tmux session with 4 panes
Screen Real Estate Minimal (one terminal) Large (2x2 grid)
Monitoring Scope Comprehensive (tests+docs+doctests) Granular (separate panes for each)
Visual Separation Sequential output in one stream Parallel output in dedicated panes
Ideal For Focused development, laptop screens Multi-monitor setups, visual dashboards
Tmux Knowledge Not required Helpful for navigation
Resource Usage Lower (one monitor) Higher (4 monitors)
Event-Driven Yes (file system events) Yes (check.fish pane) + bacon auto-rebuild

When to use each:

  • Use standalone watch: When you want simple, focused monitoring in a single terminal
  • Use tmux dashboard: When you want comprehensive visibility with separate panes for each concern

Both approaches use the same check.fish --watch script in different contexts - standalone for simplicity, integrated for comprehensive dashboards.

Typical Development Session:

  1. Start session: fish run.fish dev-dashboard
  2. Monitor panes to catch issues while coding
  3. Switch to specific pane for detailed investigation if needed
  4. All four monitors provide continuous feedback on code quality

Status Monitoring Scripts

For developers who want ultra-minimal status monitoring, this project includes two bash scripts designed for integration with the GNOME Executor extension. These scripts provide at-a-glance status indicators in your GNOME top bar.

Quick Status Scripts:

Script Purpose Success Output Failure Output
test-status-one-line.bash Run tests and show emoji status 🧪✔️ 🧪❌
doc-status-one-line.bash Build docs and show emoji status 📚✔️ 📚❌

Key Features:

  • Single-line output: Perfect for status bars and monitoring systems
  • Emoji-only status: Universal visual language requiring no text parsing
  • Silent operation: All cargo output is suppressed, only status emoji appears
  • Directory-independent: Scripts work from anywhere by changing to project directory
  • Fast execution: Optimized for quick status checks without verbose output

Usage Examples:

# Quick test status check
./test-status-one-line.bash
# Output: " 🧪✔️"

# Quick documentation build check
./doc-status-one-line.bash
# Output: " 📚✔️"

Integration with Development Workflow:

  • Complements Bacon: While bacon provides rich interactive feedback, these scripts offer minimal monitoring
  • CI/CD friendly: Perfect for automated pipelines requiring simple pass/fail status
  • GNOME integration: Designed specifically for desktop environment status bar integration
  • Background monitoring: Ideal for continuous status monitoring without interrupting workflow

These scripts provide the same underlying functionality as the bacon workflows but with radically different output designed for external consumption rather than developer interaction.

Wild Linker (Linux)

This project uses the Wild linker as a fast alternative to the default linker on Linux systems. Wild can significantly reduce link times during iterative development, making builds faster and more responsive.

Automatic Configuration: The build system automatically detects and configures Wild when both clang and wild are installed. If either tool is missing, the configuration gracefully falls back to standard parallel compilation without Wild.

Installation: The setup process automatically installs both prerequisites:

  • clang: Installed by bootstrap.sh as a system dependency
  • wild-linker: Installed by fish run.fish install-cargo-tools via cargo-binstall (with fallback to cargo install)

Configuration: When available, Wild is configured in .cargo/config.toml for Linux targets:

[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = [
    "-Z", "threads=8",  # Parallel compilation
    "-C", "link-arg=--ld-path=wild"  # Wild linker
]

Verification: Check if Wild is active by looking for the configuration in .cargo/config.toml or by observing faster link times during development builds.

Platform Support: Wild linker is Linux-only. On other platforms, the build system uses standard parallel compilation without Wild.

Rust Toolchain Management

This project includes three complementary scripts for comprehensive Rust toolchain management, each serving a specific purpose in the development workflow.

Concurrency Safety: Toolchain modification scripts (rust-toolchain-update.fish and rust-toolchain-sync-to-toml.fish) use mkdir (atomic directory creation) to ensure only one toolchain modification runs at a time. Validation scripts (rust-toolchain-validate.fish and check.fish) are lock-free since they only read toolchain state - multiple validations can run concurrently without conflict.

Why mkdir for Locking?

The key insight is understanding atomicity - when a system operation must check-and-act in a way that's guaranteed to be indivisible:

The Problem with File Existence Checks:

Traditional approaches try to check if a lock exists, then create it:

# UNSAFE - Race condition!
if [ ! -f lock ]; then
    echo "timestamp" > temp
    mv temp lock  # TOCTOU race between check and move
fi

Between the check ([ ! -f lock ]) and the move (mv temp lock), another process can slip in and also acquire the lock. This is called a Time-Of-Check-Time-Of-Use (TOCTOU) race condition.

How mkdir Works - Atomic Check-and-Create:

mkdir is different. It combines the check and create into ONE indivisible kernel operation:

# SAFE - Atomic operation
mkdir lock_dir  # Check AND create in ONE kernel operation
# Only ONE process succeeds; all others fail

When mkdir runs, the kernel does:

  1. Check: Does the directory exist?
  2. Create: If not, create it
  3. Return: With ONE atomic operation - not two separate steps

Even with perfect timing and multiple processes starting simultaneously, only ONE can create the directory.

Technical Implementation:

# In script_lib.fish
if mkdir ./rust-toolchain-script.lock 2>/dev/null
    # Lock acquired - this process has exclusive access
else
    # Lock held by another process
fi

Key Advantages:

  • Atomic: Check-and-create in ONE kernel operation (impossible to race)
  • Simple: No file descriptors or special handling needed
  • Reliable: Works on all Unix systems (standard POSIX behavior)
  • Stale lock detection: Automatically removes locks older than 10 minutes (crashed processes)
  • Crash-safe: Abandoned locks are auto-cleaned after 10 minutes, or manually via rm -rf rust-toolchain-script.lock

The locking mechanism uses:

  • mkdir (atomic directory creation): Creates lock directory atomically - succeeds for one process, fails for all others
  • Atomic kernel operation: Check-and-create happens as ONE indivisible operation - the definition of mutual exclusion
  • Timestamp tracking: Stores creation time in rust-toolchain-script.lock/timestamp for age tracking
  • Stale lock detection: Checks lock age on collision - auto-removes if older than 10 minutes (600 seconds)
  • Lock holder cleanup: Process that acquired lock removes directory (including timestamp) when done
  • Conflict detection: Failed mkdir indicates lock is held - shows age for transparency
  • Standard Unix pattern: Used by systemd, init systems, and most Unix tools

1. rust-toolchain-update.fish - Smart Validated Toolchain Updates

Intelligently finds and validates a stable nightly toolchain, preferring older versions for stability while ensuring they don't have ICE (Internal Compiler Error) bugs.

# Via run.fish command
fish run.fish toolchain-update

# Or directly
./rust-toolchain-update.fish

What it does:

  • Smart search: Tests nightly toolchains starting from 45 days ago, moving forward day-by-day until finding a stable one (up to today)
  • ICE validation: Runs comprehensive validation suite on each candidate:
    • cargo clippy --all-targets
    • cargo build
    • cargo test --all-targets
    • cargo test --doc
    • cargo doc --no-deps
  • Toolchain vs code errors: Distinguishes between:
    • ICE errors (compiler crashes) → rejects toolchain, tries next day
    • Code errors (compilation/test failures) → accepts toolchain (validates compiler works, not your code)
  • First stable wins: Stops at the first toolchain without ICE errors (usually finds stable toolchain in first attempt)
  • Updates rust-toolchain.toml to use the validated stable nightly
  • Installs the target toolchain with rust-analyzer component (required by IDEs, cargo, and serena MCP server)
  • Desktop notifications (via notify-send):
    • 🎉 Success notification when stable toolchain found (normal urgency)
    • 🚨 Critical alert if no stable toolchain found in entire 45-day window (extremely rare)
  • Performs aggressive cleanup by removing all old nightly toolchains except:
    • All stable toolchains (stable-*)
    • The newly validated nightly
  • Final verification with fresh build:
    • Removes ICE failure files (rustc-ice-*.txt) generated during validation
    • Cleans all caches: cargo cache, build artifacts
    • Runs full verification: tests, doctests, and documentation build
    • Ensures new toolchain works perfectly from scratch
  • Logs all operations to /home/nazmul/Downloads/rust-toolchain-update.log

When to use:

  • Weekly maintenance (can be automated via systemd timer)
  • When you want to update to a validated stable nightly
  • When you want to clean up old toolchains
  • After encountering ICE errors with current toolchain

Example output:

═══════════════════════════════════════════════════════
Starting search for stable toolchain
Strategy: Start 45 days ago, try progressively newer up to today
Search window: 2025-08-29 to 2025-10-13
═══════════════════════════════════════════════════════

Attempt 1/46
Trying toolchain: nightly-2025-08-29 (45 days ago)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Validating toolchain: nightly-2025-08-29
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Running validation step: clippy
  ⚠️  Command exited with code 101 (this is OK if not ICE)
  ✅ No ICE detected - continuing validation
...
✅ Toolchain nightly-2025-08-29 is STABLE (no ICE detected)

🎉 FOUND STABLE TOOLCHAIN: nightly-2025-08-29
Success notification sent

✅ Successfully updated rust-toolchain.toml
✅ Successfully installed rust-analyzer component
Removed 2 old toolchain(s)
Toolchains directory size before cleanup: 5.3G
Toolchains directory size after cleanup: 2.6G

2. rust-toolchain-sync-to-toml.fish - Sync to Existing Config

Syncs your Rust environment to match whatever is specified in rust-toolchain.toml.

# Via run.fish command
fish run.fish toolchain-sync

# Or directly
./rust-toolchain-sync-to-toml.fish

What it does:

  • Reads the channel value from rust-toolchain.toml (doesn't modify it)
  • Installs the exact toolchain specified in the TOML
  • Installs rust-analyzer and rust-src components automatically (required by IDEs, cargo, and serena MCP server)
  • Performs aggressive cleanup by removing all old nightly toolchains except:
    • All stable toolchains (stable-*)
    • The target toolchain from the TOML
  • Logs all operations to /home/nazmul/Downloads/rust-toolchain-sync-to-toml.log

When to use:

  • After git checkout/reset/pull changes rust-toolchain.toml
  • When rust-analyzer is missing for the current toolchain
  • When your IDE shows "rust-analyzer failed to start"
  • When Claude Code's serena MCP server crashes with LSP initialization errors
  • After manually editing rust-toolchain.toml
  • When you need to stay on a specific nightly version

Key difference from update script:

  • This script (sync): Respects TOML → Installs what's specified
  • Update script: Modifies TOML → Installs "1 month ago" nightly

Example workflow:

# Weekly script updates TOML to nightly-2025-09-11
# But you need to stay on nightly-2025-09-05 for testing a specific feature
git checkout rust-toolchain.toml  # Revert to 09-05
fish run.fish toolchain-sync  # Install components for 09-05
# Now rust-analyzer works for 09-05

3. rust-toolchain-validate.fish - Unified Toolchain Validation

Consolidated validation script providing two modes: quick component check or comprehensive build+test validation.

# Quick mode: Fast component check (~1-2 seconds)
fish run.fish toolchain-validate
./rust-toolchain-validate.fish quick

# Complete mode: Full build+test validation (~5-10 minutes)
fish run.fish toolchain-validate-complete
./rust-toolchain-validate.fish complete

# View detailed help
./rust-toolchain-validate.fish

Mode Comparison:

Aspect Quick Mode Complete Mode
Time ~1-2 seconds ~5-10 minutes
Purpose Component verification Stability verification
Use Case Fast health checks Pre-nightly validation
Checks Installation + components + rustc works Full build + clippy + tests + docs
ICE Detection No Yes (critical for nightly selection)

Quick Mode Validation:

  • ✅ Toolchain is installed via rustup
  • ✅ rust-analyzer component is present
  • ✅ rust-src component is present
  • ✅ rustc --version works (not corrupted)

Complete Mode Validation:

  • ✅ All quick mode checks
  • ✅ cargo clippy --all-targets (no ICE)
  • ✅ cargo build (no ICE)
  • ✅ cargo test --all-targets (no ICE)
  • ✅ cargo test --doc (no ICE)
  • ✅ cargo doc --no-deps (no ICE)

Return Codes:

  • 0: ✅ Valid (quick) or Stable (complete)
  • 1: ❌ Not installed (quick) or ICE detected (complete)
  • 2: ⚠️ Missing components (quick only)
  • 3: 🔥 Corrupted - rustc fails (quick only)
  • 4: ❌ Failed to read rust-toolchain.toml

When to use Quick Mode:

  • After installing/repairing toolchain with sync-toolchain
  • Troubleshooting IDE issues (rust-analyzer not working?)
  • Pre-flight check before running tests
  • Regular health monitoring
  • Part of automated CI/CD pipelines

When to use Complete Mode:

  • Verifying nightly toolchain stability before using it
  • Detecting Internal Compiler Errors (ICE) in compiler
  • Before committing code with new toolchain
  • During toolchain-update search (finding stable nightly)
  • After major Rust version updates

Integration with other toolchain scripts:

  • check.fish: Uses quick mode to check toolchain before running tests; calls toolchain-sync if invalid
  • rust-toolchain-sync-to-toml.fish: Performs quick validation after installing components
  • rust-toolchain-update.fish: Uses complete mode to find stable nightly

4. remove_toolchains.sh - Testing Utility

Removes ALL Rust toolchains for testing upgrade progress display (⚠️ DESTRUCTIVE).

./remove_toolchains.sh

What it does:

  • Removes ALL Rust toolchains from your system
  • Cleans up toolchain directories completely
  • Creates a clean slate for testing rustup installation progress

When to use:

  • When developing/testing the upgrade progress display in edi and giti
  • To see full rustup download and installation progress
  • For testing cmdr/src/analytics_client/upgrade_check.rs functionality

Recovery after testing:

rustup toolchain install stable && rustup default stable
# Or
fish run.fish toolchain-update

⚠️ Warning: This is a destructive testing utility. Use only when you understand the implications and are prepared to reinstall toolchains.

Log File Output

All toolchain management scripts display detailed log file locations to stdout at startup:

📋 Detailed log: /home/nazmul/Downloads/rust-toolchain-sync-to-toml.log

This makes it easy to monitor progress and check detailed logs after operations complete:

# Watch logs in real-time
tail -f /home/nazmul/Downloads/rust-toolchain-update.log

# Or review after completion
cat /home/nazmul/Downloads/rust-toolchain-sync-to-toml.log

Comprehensive Toolchain Management System

The four scripts work together to provide a complete toolchain management solution:

Four complementary scripts:

  • validate (rust-toolchain-install-validate.fish): Non-destructive validation of current toolchain
  • update (rust-toolchain-update.fish): Smart search for stable nightly with comprehensive validation
  • sync (rust-toolchain-sync-to-toml.fish): Install toolchain matching rust-toolchain.toml
  • remove (remove_toolchains.sh): Testing utility to clean all toolchains (destructive)

Key benefits:

  • Stability: Month-old nightlies have proven stability while providing recent features
  • Disk space savings: Aggressive cleanup removes accumulated old toolchains
  • Consistency: All developers use the same Rust version via rust-toolchain.toml
  • Automation ready: update script designed to run weekly via systemd timer
  • Recovery ready: sync script fixes environment after git operations
  • Validation ready: validate script enables automated health checks in CI/CD pipelines
  • Testing support: remove script enables testing upgrade workflows
  • Integrated monitoring: check.fish automatically validates and repairs toolchain before running tests

Unified Script Architecture

The project uses a clean separation of concerns across three main scripts:

bootstrap.sh - OS-Level Setup

  • System package manager detection and OS dependencies
  • Rust toolchain installation via rustup
  • Development environment setup (Fish shell, fzf, file watchers)
  • Cross-platform compatibility (Linux, macOS)
  • Calls run.fish for Rust-specific tooling

run.fish - Rust Development Commands

  • Workspace-wide commands that operate on the entire project
  • Cargo tool installation (install-cargo-tools with cargo-binstall, uv, bacon, etc.)
  • TUI-specific commands for running examples and benchmarks
  • cmdr-specific commands for binary management
  • Cross-platform file watching using inotifywait (Linux) or fswatch (macOS)
  • Smart log monitoring that detects and manages log files from different workspaces

script_lib.fish - Shared Utilities

  • Common functions used by both bootstrap.sh and run.fish
  • Utility functions: install_if_missing, generate_cargo_config, install_cargo_tool
  • Cross-platform package manager detection

All commands work from the root directory, eliminating the need to navigate between subdirectories. This architecture ensures no redundancy - each tool is installed in exactly one place with clear ownership.

Star History

Star History Chart

Archive

As this repo grows, changes, and matures, pruning is necessary. The r3bl-open-core-archive is where all the code and artifacts that are no longer needed are moved to.

This way nothing is "lost" and if you need to use some of the code that was removed, you can find it there.

Also if you want to make changes to this code and maintain it yourself, please let us know.

  1. You can submit PRs and we can also accept them, and publish them to crates.io if that makes sense.
  2. Or we can even work out and arrangements to move ownership of the code & crate to you if you would like to commit to maintaining it.