← Blog
April 18, 2026

MentisDB 0.9.3.39 — Full TUI with Drag-to-Copy, Seamless Startup, and Live Log Streaming

0.9.3.39 ships the ratatui terminal UI that was always planned for mentisdb: a live three-pane dashboard with real-time log streaming, a tabbed registry for all your chains, agents, and skills, and a one-click agent primer. Along the way, we fixed a collection of bugs that made the TUI unreliable — a silent startup crash, a flash on startup, logs frozen at the oldest entry, and clipboard copy that silently did nothing. Every one of those is gone.

Select any text, get it in your clipboard. Drag the mouse across any content in the TUI — log lines, storage paths, chain keys, endpoint URLs, config values, the primer paste line — and release. The selected rectangle is read directly from ratatui's render buffer, written to the clipboard via arboard and OSC 52, and confirmed with a green toast. No pane restrictions, no key chords required.

The TUI at a Glance

Run mentisdb in an interactive terminal and you get a full alternate-screen dashboard:

All panes have scrollbars and respond to Tab/Shift-Tab for keyboard focus cycling. Run in background (nohup mentisdb &) and you get the same daemon with no TUI overhead.

Drag-to-Select Copy — How It Works

Getting this right required solving a non-obvious ratatui timing problem. The naive approach — read terminal.current_buffer_mut() after terminal.draw() returns — silently fails every time. After draw(), ratatui swaps its internal buffer indices: the "current" buffer now points to the cleared, reset buffer prepared for the next frame. The just-rendered content lives in what was the previous buffer, and there is no direct public accessor for it.

The fix: queue the extraction as pending_extract = Some((start, end)) on MouseUp. On the next iteration, inside the terminal.draw() closure, frame.buffer_mut() is the live pre-swap buffer — full of the just-rendered characters. The extraction happens there, the result is stored, and immediately after draw() returns the clipboard write and toast fire.

Clipboard delivery uses two paths simultaneously:

Seamless Single-TUI Lifecycle

Previously the daemon ran two TUI instances: one for startup progress, one for the running state. Between them the alternate screen was exited and re-entered, causing a visible flash that looked like a crash. The daemon now runs exactly one run_tui() call for its entire lifetime. Startup transitions seamlessly from the progress overlay to the fully-populated running view without the terminal flickering.

Startup Crash Overlay

When startup fails — a port conflict, a bad config, a migration error — the previous daemon exited silently, leaving the user nothing to debug. Now a red full-screen overlay shows the error message and keeps the TUI alive with a scrollable log panel. The user reads the error, scrolls to find the relevant log line, and presses q to quit. No silent death.

Log Auto-Scroll Fix

The log panel renders entries newest-first. Auto-scroll was setting log_scroll = len - 1 — the bottom of the reversed list, which is the oldest entry. New log messages appeared at position 0 (top) but the viewport was pinned to the bottom, making the panel appear frozen even while agents were actively writing to memory. Fixed: auto-scroll now keeps log_scroll = 0, pinned to the newest entry at the top.

Other Improvements

Upgrade

cargo install mentisdb --force

The daemon binary is mentisdb. Run it directly in a terminal for the TUI, or with nohup mentisdb & for background operation.