Skip to main content

Component Architecture

MonoTerm consists of four main components working in a carefully designed pipeline.

System Overview

╔═══════════════════════════════════════════════════════════════════════╗
║                                                                        ║
║  MONOTERM ARCHITECTURE                                                 ║
║                                                                        ║
║                                                                        ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │                                                          │       ║
║    │                    PTY DAEMON                            │       ║
║    │               (Separate Process)                         │       ║
║    │                                                          │       ║
║    │   * Manages shell processes (bash, zsh, fish)           │       ║
║    │   * Survives application crashes                        │       ║
║    │   * One daemon serves multiple terminals                │       ║
║    │                                                          │       ║
║    └─────────────────────────────┬────────────────────────────┘       ║
║                                  │                                    ║
║                                  │ Unix Socket                        ║
║                                  │ (Raw PTY bytes)                    ║
║                                  v                                    ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │                                                          │       ║
║    │                  RUST BACKEND (Tauri)                    │       ║
║    │                                                          │       ║
║    │   ┌──────────────────────────────────────────────────┐   │       ║
║    │   │           SessionActor                           │   │       ║
║    │   │   (Manages all terminal sessions)                │   │       ║
║    │   └──────────────────────────────────────────────────┘   │       ║
║    │                        │                                 │       ║
║    │                        v                                 │       ║
║    │   ┌──────────────────────────────────────────────────┐   │       ║
║    │   │           GridWorker                             │   │       ║
║    │   │   ┌──────────────────────────────────────────┐   │   │       ║
║    │   │   │      Alacritty VTE Parser                │   │   │       ║
║    │   │   │   (Interprets escape sequences)          │   │   │       ║
║    │   │   └──────────────────────────────────────────┘   │   │       ║
║    │   └──────────────────────────────────────────────────┘   │       ║
║    │                                                          │       ║
║    └─────────────────────────────┬────────────────────────────┘       ║
║                                  │                                    ║
║                                  │ Tauri Event                        ║
║                                  │ (Grid Update)                      ║
║                                  v                                    ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │                                                          │       ║
║    │                TYPESCRIPT FRONTEND                       │       ║
║    │                                                          │       ║
║    │   ┌──────────────────────────────────────────────────┐   │       ║
║    │   │        Grid Injector                             │   │       ║
║    │   │   (Receives updates, injects to display)         │   │       ║
║    │   └──────────────────────────────────────────────────┘   │       ║
║    │                        │                                 │       ║
║    │                        v                                 │       ║
║    │   ┌──────────────────────────────────────────────────┐   │       ║
║    │   │           xterm.js + WebGL                       │   │       ║
║    │   │   (GPU-accelerated rendering)                    │   │       ║
║    │   └──────────────────────────────────────────────────┘   │       ║
║    │                                                          │       ║
║    └──────────────────────────────────────────────────────────┘       ║
║                                                                        ║
╚═══════════════════════════════════════════════════════════════════════╝

Component 1: PTY Daemon

The PTY Daemon runs as a separate sidecar process from the main application.
╔═══════════════════════════════════════════════════════════════════════╗
║                                                                        ║
║  PTY DAEMON                                                            ║
║                                                                        ║
║    Purpose:                                                            ║
║    * Manage shell processes (bash, zsh, fish)                         ║
║    * Provide session persistence across app restarts                  ║
║    * Isolate PTY management from UI process                           ║
║                                                                        ║
║                                                                        ║
║    Process Isolation:                                                  ║
║                                                                        ║
║    ┌──────────────────┐         ┌──────────────────┐                   ║
║    │   Main App       │         │   PTY Daemon     │                   ║
║    │   (Tauri)        │         │   (Sidecar)      │                   ║
║    │                  │         │                  │                   ║
║    │   If app         │         │   Daemon         │                   ║
║    │   crashes...     │  ───▶   │   keeps          │                   ║
║    │                  │         │   running        │                   ║
║    │   X UI dies      │         │   OK Shells      │                   ║
║    │                  │         │      survive     │                   ║
║    └──────────────────┘         └──────────────────┘                   ║
║                                                                        ║
║                                                                        ║
║    Communication:                                                      ║
║                                                                        ║
║    ┌─────────────┐     Unix Socket      ┌─────────────┐                ║
║    │   Tauri     │ ◀──────────────────▶ │   Daemon    │                ║
║    │   Backend   │   /tmp/pty-xxx.sock  │             │                ║
║    └─────────────┘                      └─────────────┘                ║
║                                                                        ║
║    * One socket per terminal session                                   ║
║    * Bidirectional: read output, write input                          ║
║    * Raw bytes (no JSON overhead)                                     ║
║                                                                        ║
╚═══════════════════════════════════════════════════════════════════════╝

Component 2: SessionActor (Rust Backend)

The SessionActor is the central coordinator using the Actor Model pattern.
╔═══════════════════════════════════════════════════════════════════════╗
║                                                                        ║
║  SESSIONACTOR - Lock-Free Session Management                           ║
║                                                                        ║
║                                                                        ║
║    Design Pattern: Actor Model                                         ║
║                                                                        ║
║    * Single point of ownership for all state                          ║
║    * No locks needed (MPSC message passing only)                      ║
║    * Commands processed sequentially                                  ║
║                                                                        ║
║                                                                        ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │                                                          │       ║
║    │                   SESSIONACTOR                           │       ║
║    │                                                          │       ║
║    │   Owned State:                                           │       ║
║    │                                                          │       ║
║    │   sessions: { session_id ──▶ SessionState }               │       ║
║    │   grid_workers: { session_id ──▶ GridWorker channel }     │       ║
║    │                                                          │       ║
║    │                                                          │       ║
║    │   Commands Handled:                                      │       ║
║    │                                                          │       ║
║    │   * CreateSession     ──▶ Start new terminal              │       ║
║    │   * CloseSession      ──▶ End terminal                    │       ║
║    │   * ResizeSession     ──▶ Change dimensions               │       ║
║    │   * WriteToPty        ──▶ Send input to shell             │       ║
║    │   * PtyData           ──▶ Received output from shell      │       ║
║    │   * GridAck           ──▶ Flow control acknowledgment     │       ║
║    │                                                          │       ║
║    └──────────────────────────────────────────────────────────┘       ║
║                                                                        ║
║                                                                        ║
║    Message Flow:                                                       ║
║                                                                        ║
║    Frontend                SessionActor              Workers           ║
║        │                        │                        │             ║
║        │   CreateSession        │                        │             ║
║        │ ─────────────────────▶ │                        │             ║
║        │                        │   Spawn GridWorker     │             ║
║        │                        │ ─────────────────────▶ │             ║
║        │                        │                        │             ║
║        │   WriteToPty           │                        │             ║
║        │ ─────────────────────▶ │                        │             ║
║        │                        │   Forward to PTY       │             ║
║        │                        │ ───────────────────▶   │             ║
║        │                        │                        │             ║
║        │                        │   PtyData received     │             ║
║        │                        │ ◀───────────────────   │             ║
║        │                        │   Send to GridWorker   │             ║
║        │                        │ ─────────────────────▶ │             ║
║        │                        │                        │             ║
║                                                                        ║
╚═══════════════════════════════════════════════════════════════════════╝

Component 3: GridWorker + Alacritty VTE Parser

Each terminal session has its own GridWorker with an embedded VTE parser.
╔═══════════════════════════════════════════════════════════════════════╗
║                                                                        ║
║  GRIDWORKER (One Per Terminal Session)                                 ║
║                                                                        ║
║                                                                        ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │                                                          │       ║
║    │                    GRIDWORKER                            │       ║
║    │                                                          │       ║
║    │    Input Channel (MPSC)                                  │       ║
║    │                                                          │       ║
║    │    Receives:                                             │       ║
║    │      * Data(bytes)   - PTY output to process             │       ║
║    │      * Resize(w,h)   - Terminal size changed             │       ║
║    │      * Ack           - Frontend ready for more           │       ║
║    │                                                          │       ║
║    │                                                          │       ║
║    │    ┌──────────────────────────────────────────────────┐  │       ║
║    │    │                                                  │  │       ║
║    │    │          ALACRITTY VTE PARSER                    │  │       ║
║    │    │                                                  │  │       ║
║    │    │   * State machine for escape sequences           │  │       ║
║    │    │   * CSI sequence handling                        │  │       ║
║    │    │   * OSC command processing                       │  │       ║
║    │    │   * UTF-8 decoding                               │  │       ║
║    │    │                                                  │  │       ║
║    │    └──────────────────────────────────────────────────┘  │       ║
║    │                          │                               │       ║
║    │                          v                               │       ║
║    │    ┌──────────────────────────────────────────────────┐  │       ║
║    │    │      Grid State (Terminal Content)               │  │       ║
║    │    │                                                  │  │       ║
║    │    │   * Cell contents (characters)                   │  │       ║
║    │    │   * Cell attributes (colors, styles)             │  │       ║
║    │    │   * Cursor position                              │  │       ║
║    │    │   * Scrollback history                           │  │       ║
║    │    │                                                  │  │       ║
║    │    └──────────────────────────────────────────────────┘  │       ║
║    │                                                          │       ║
║    │                                                          │       ║
║    │    Output: Grid Update (cells, cursor, DiffHint)         │       ║
║    │                                                          │       ║
║    └──────────────────────────────────────────────────────────┘       ║
║                                                                        ║
║                                                                        ║
║    Why Alacritty VTE Parser?                                           ║
║                                                                        ║
║      * Battle-tested in production terminal                           ║
║      * Excellent escape sequence compatibility                        ║
║      * Fast Rust implementation                                       ║
║      * Well-maintained and documented                                 ║
║                                                                        ║
╚═══════════════════════════════════════════════════════════════════════╝

Component 4: Grid Injector (TypeScript Frontend)

The frontend component that receives Grid Updates and injects them into xterm.js.
╔═══════════════════════════════════════════════════════════════════════╗
║                                                                        ║
║  GRID INJECTOR                                                         ║
║                                                                        ║
║                                                                        ║
║    Purpose:                                                            ║
║    * Listen for Grid Update events from Rust                          ║
║    * Validate updates (EPOCH check)                                   ║
║    * Inject cell data directly into xterm.js                          ║
║    * Send ACK back to Rust for flow control                           ║
║                                                                        ║
║                                                                        ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │                                                          │       ║
║    │               GRID INJECTOR                              │       ║
║    │                                                          │       ║
║    │    Event Listener                                        │       ║
║    │                                                          │       ║
║    │    listen("pty-grid-{sessionId}")                        │       ║
║    │         │                                                │       ║
║    │         v                                                │       ║
║    │    ┌──────────────────────────────────────────────┐      │       ║
║    │    │       Epoch Validation                       │      │       ║
║    │    │                                              │      │       ║
║    │    │  if (update.epoch < currentEpoch)            │      │       ║
║    │    │      ──▶ DISCARD (stale update)              │      │       ║
║    │    │                                              │      │       ║
║    │    │  if (update.size != xterm.size)              │      │       ║
║    │    │      ──▶ REQUEST RESIZE                      │      │       ║
║    │    │                                              │      │       ║
║    │    └──────────────────────────────────────────────┘      │       ║
║    │         │                                                │       ║
║    │         v                                                │       ║
║    │    ┌──────────────────────────────────────────────┐      │       ║
║    │    │       Direct Injection                       │      │       ║
║    │    │                                              │      │       ║
║    │    │  For each row in update:                     │      │       ║
║    │    │    Write cells directly to xterm.js          │      │       ║
║    │    │    Set cursor position                       │      │       ║
║    │    │    Trigger WebGL refresh                     │      │       ║
║    │    │                                              │      │       ║
║    │    └──────────────────────────────────────────────┘      │       ║
║    │         │                                                │       ║
║    │         v                                                │       ║
║    │    ┌──────────────────────────────────────────────┐      │       ║
║    │    │       Send ACK                               │      │       ║
║    │    │                                              │      │       ║
║    │    │  invoke("grid_ack", { sessionId })           │      │       ║
║    │    │                                              │      │       ║
║    │    └──────────────────────────────────────────────┘      │       ║
║    │                                                          │       ║
║    └──────────────────────────────────────────────────────────┘       ║
║                                                                        ║
╚═══════════════════════════════════════════════════════════════════════╝

Complete Data Flow

The journey of a single command through the entire system.
╔═══════════════════════════════════════════════════════════════════════╗
║                                                                        ║
║  DATA FLOW: User Types "ls" and Presses Enter                          ║
║                                                                        ║
║                                                                        ║
║    ┌──────────┐                                                        ║
║    │  User    │                                                        ║
║    │ Keyboard │                                                        ║
║    └────┬─────┘                                                        ║
║         │                                                              ║
║         │ 1. Keypress events: 'l', 's', 'Enter'                        ║
║         v                                                              ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │  xterm.js                                                 │       ║
║    │  Captures keypress, sends to backend                      │       ║
║    └─────────────────────────────┬────────────────────────────┘        ║
║                                  │                                     ║
║         2. invoke("write_to_pty", { data: "ls\n" })                    ║
║                                  │                                     ║
║                                  v                                     ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │  Tauri Backend (SessionActor)                             │       ║
║    │  Forwards to PTY Daemon                                   │       ║
║    └─────────────────────────────┬────────────────────────────┘        ║
║                                  │                                     ║
║         3. Write "ls\n" to Unix socket                                 ║
║                                  │                                     ║
║                                  v                                     ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │  PTY Daemon                                               │       ║
║    │  Sends to shell, shell executes "ls"                      │       ║
║    └─────────────────────────────┬────────────────────────────┘        ║
║                                  │                                     ║
║         4. Shell output: "file1.txt\nfile2.txt\n$ "                    ║
║                                  │                                     ║
║                                  v                                     ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │  Tauri Backend (SessionActor)                             │       ║
║    │  Receives PTY data, sends to GridWorker                   │       ║
║    └─────────────────────────────┬────────────────────────────┘        ║
║                                  │                                     ║
║         5. MPSC Message: Data(bytes)                                   ║
║                                  │                                     ║
║                                  v                                     ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │  GridWorker + Alacritty VTE Parser                        │       ║
║    │  Parse escape sequences, update grid state                │       ║
║    └─────────────────────────────┬────────────────────────────┘        ║
║                                  │                                     ║
║         6. emit("pty-grid-xxx", GridUpdate)                            ║
║                                  │                                     ║
║                                  v                                     ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │  Grid Injector                                            │       ║
║    │  Inject cells directly into xterm.js                      │       ║
║    └─────────────────────────────┬────────────────────────────┘        ║
║                                  │                                     ║
║         7. Direct write to xterm.js internal structures                ║
║                                  │                                     ║
║                                  v                                     ║
║    ┌──────────────────────────────────────────────────────────┐       ║
║    │  xterm.js + WebGL                                         │       ║
║    │  GPU-accelerated rendering                                │       ║
║    └─────────────────────────────┬────────────────────────────┘        ║
║                                  │                                     ║
║         8. User sees "file1.txt\nfile2.txt\n$ "                        ║
║                                  │                                     ║
║                                  v                                     ║
║    ┌──────────┐                                                        ║
║    │ Display  │                                                        ║
║    └──────────┘                                                        ║
║                                                                        ║
╚═══════════════════════════════════════════════════════════════════════╝

Key Technologies

ComponentTechnologyPurpose
PTY DaemonRust Sidecar BinarySession persistence, crash isolation
SessionActorRust + MPSC ChannelsLock-free session management
VTE ParserAlacritty (Rust)Native-speed escape sequence parsing
Rendererxterm.js + WebGLGPU-accelerated display
IPCTauri EventsEfficient frontend-backend communication