Architecture

Technical overview of repartee's internal design.

Technology stack

Component Technology
Language Rust 2024 edition
TUI framework ratatui 0.30+ with crossterm backend
Async runtime tokio (full features)
IRC protocol irc crate v1.1.0
Scripting Lua 5.4 via mlua 0.11
Storage SQLite via rusqlite (bundled)
Encryption AES-256-GCM via aes-gcm
Error handling color-eyre + thiserror
Config TOML via serde

TEA architecture

repartee follows The Elm Architecture (TEA) pattern:

Model → Message → Update → View
  • Model: AppState — all application state (buffers, connections, config)
  • Message: Events from IRC, keyboard, mouse, timers
  • Update: Event handlers that transform state
  • View: ratatui rendering functions that read state

State is UI-agnostic — the state/ module has no ratatui imports.

Module structure

src/
  main.rs              # Entry point, terminal setup
  app.rs               # Main event loop, App struct
  constants.rs         # APP_NAME and global constants
  config/              # TOML config loading
  state/               # Application state (buffers, connections, sorting)
  irc/                 # IRC connection, event handling, formatting
    events.rs          # IRC message → state update
    mod.rs             # Connection setup, CAP negotiation, SASL
    cap.rs             # IRCv3 CAP framework
    isupport.rs        # ISUPPORT parameter parsing
    batch.rs           # IRCv3 BATCH (netsplit/netjoin)
    sasl_scram.rs      # SASL SCRAM-SHA-256 implementation
    extban.rs          # Extended ban types ($a:account, etc.)
    flood.rs           # Flood protection
    netsplit.rs        # Netsplit detection
    ignore.rs          # Ignore list matching
    formatting.rs      # IRC formatting helpers
  ui/                  # TUI rendering
    layout.rs          # Screen layout + regions
    buffer_list.rs     # Left sidebar
    nick_list.rs       # Right sidebar
    chat_view.rs       # Message display
    input.rs           # Command input + tab completion
    status_line.rs     # Bottom status bar
    topic_bar.rs       # Top topic display
    message_line.rs    # Single message rendering
    styled_text.rs     # Format string → ratatui spans
  theme/               # Theme loading + format string parser
  scripting/           # Lua scripting engine
    engine.rs          # ScriptEngine trait + ScriptManager
    api.rs             # Event names
    event_bus.rs       # Priority-ordered event dispatch
    lua/               # Lua 5.4 backend (mlua)
  storage/             # SQLite logging
    db.rs              # Database schema + migrations
    writer.rs          # Batched async writer
    query.rs           # Search + read queries
    crypto.rs          # AES-256-GCM encryption
    types.rs           # LogRow, StoredMessage
  commands/            # Command system
    parser.rs          # /command arg parsing
    registry.rs        # Command registration
    handlers_irc.rs    # IRC commands (/join, /msg, etc.)
    handlers_ui.rs     # UI commands (/clear, /close, etc.)
    handlers_admin.rs  # Admin commands (/set, /reload, etc.)
    docs.rs            # Command documentation loader

Event flow

  1. Terminal events (keyboard, mouse) arrive via crossterm event::poll in a spawn_blocking thread
  2. Events are sent through a tokio mpsc channel to the main loop
  3. IRC events arrive via the irc crate's async reader, converted to IrcEvent enum variants
  4. The main loop in App::run() processes all events sequentially, updating AppState
  5. After each event batch, the UI is re-rendered from the current state

IRC connection layer

Each server connection spawns:

  • An async reader task that receives IRC messages and sends IrcEvent to a shared mpsc channel
  • Messages are sent through the irc crate's Sender stored in the connection state

All connections share a single event channel, with events tagged by connection_id.

Scripting architecture

ScriptManager
  └── Vec<Box<dyn ScriptEngine>>
        └── LuaEngine (mlua)
              ├── Per-script Lua environments (sandboxed)
              ├── Event handlers (priority-sorted, per-event)
              └── Command handlers

The ScriptEngine trait allows adding new languages (Rhai, etc.) by implementing the trait and registering with ScriptManager.

IRCv3 support

repartee implements a comprehensive set of IRCv3 capabilities negotiated during connection via CAP LS/REQ/ACK:

Capability Description
multi-prefix Multiple mode prefixes per nick (e.g. @+nick)
extended-join Account name and realname in JOIN messages
server-time Message timestamps from the server
account-tag Account name on every message
cap-notify Server-side capability change notifications
away-notify Real-time away status changes
account-notify Account login/logout notifications
chghost Real-time ident/hostname changes
echo-message Authoritative echo of sent messages
invite-notify Notifications for channel invites
batch Grouped message batches (netsplit/netjoin)
userhost-in-names Full user@host in NAMES replies
message-tags Arbitrary IRCv3 message metadata

SASL mechanisms supported: PLAIN, EXTERNAL (client certificate), SCRAM-SHA-256.

WHOX (extended WHO) is auto-detected and used to populate account names and full user@host for nick entries.

Storage pipeline

AppState::add_message()
  → log_tx (tokio mpsc sender)
  → WriterTask (batches 50 rows / 1 second)
  → SQLite (WAL mode, FTS5 index)

Messages flow from the UI thread to the writer task asynchronously, ensuring zero UI blocking on disk I/O.