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.
Run mentisdb in an interactive terminal and you get a full alternate-screen
dashboard:
c to copy it instantly.c copies the selected row's
key.c to copy visible lines.
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.
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:
\x1b]52;c;<base64>\x07
written directly to stdout. This instructs the terminal emulator to set the system
clipboard, enabling Cmd+C in iTerm2, Terminal.app (macOS 14+), kitty, and WezTerm
even while mouse capture is active.
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.
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.
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.
frame.render_widget(Clear, popup_area)
before drawing their block. Background content no longer bleeds through popup
borders.mentisdb wizard in a separate
terminal instead.render_logs no longer allocates
an intermediate Vec<&str> on every frame tick; a single
.iter().rev() pass is used instead.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.