DEV Community

Rodrigo Mello
Rodrigo Mello

Posted on

Stop Losing Terminal Output: I Built a CLI That Records and Searches Your Shell Sessions

If you spend most of your day in the terminal, you've probably been here: you're debugging a service, tailing logs across three terminal tabs, hot-reloading a dev server, and then you need that one stack trace from twenty minutes ago. It's gone. Scrollback cleared, terminal closed, or simply buried under a wall of newer output.

I got tired of this. So I built broll, a Rust CLI that records your terminal sessions, stores them in SQLite with full-text search, and lets you browse everything later in a TUI.

The name comes from B-roll, the background footage in film that captures everything happening behind the main scene. That's exactly what your terminal output is: the unscripted, behind-the-scenes footage of your development work. You never think about it while it's rolling, but when something goes wrong, it's the first thing you wish you had.

cargo install broll
Enter fullscreen mode Exit fullscreen mode

The Problem

Terminal emulators give you a scrollback buffer. That buffer is finite, session-scoped, and unsearchable. If you're running a hot-reloading dev server, every restart wipes previous output. If you're working across multiple terminals, say one for your API, one for a worker, one for ad-hoc commands, correlating what happened across them later is basically impossible.

You can pipe things to files, sure. But that means knowing in advance which output you'll need later, and you lose the interactivity of your shell.

How broll Works

You wrap your shell session with broll start and work normally. When you're done, exit or broll stop. Everything in between, every command you typed and every byte of output, is captured, timestamped, and stored.

$ broll start --name "debugging-auth-issue"
# ... work normally, run commands, tail logs ...
$ exit
Enter fullscreen mode Exit fullscreen mode

Under the hood, broll spawns a PTY sub-shell and installs lightweight shell hooks (zsh preexec/precmd, bash PROMPT_COMMAND) that emit OSC escape sequences. These markers let broll's recorder distinguish what you typed from what the shell printed back, without interfering with your workflow. Your shell behaves exactly as it normally does. broll is invisible until you need it.

Captured output goes into SQLite with FTS5 full-text indexing. That means you can search across all your sessions later:

$ broll search "connection refused"
Enter fullscreen mode Exit fullscreen mode

This opens a two-panel TUI with live search: results update as you type with debounced input. Select a match and press Enter to jump into a full session viewer, scrolled right to the relevant line.

broll search TUI showing the two-panel layout with live results and preview

The TUI

The viewer and search panels are built with ratatui. A few things I'm particularly happy with:

  • Syntax highlighting for JSON, log levels (ERROR/WARN/INFO/DEBUG), URLs, and file:line references in output
  • Vim-style yank (yy, Y, V for visual line mode) to copy lines straight to your clipboard
  • Mouse support for scrolling and clicking through results
  • In-session search with / in the viewer, just like less/vim

The viewer preserves terminal formatting. broll uses a virtual terminal (vt100 crate) to render the raw captured bytes, so colored output, progress bars, and column alignment all look correct when you review them later.

broll session viewer with syntax highlighted JSON and log output

Automatic Secret Redaction

Since terminal sessions can contain sensitive content like environment variables with tokens, API keys, database URLs, or JWTs, broll runs all captured output through a redaction filter before storing it. Regex patterns match seven categories of secrets (AWS keys, bearer tokens, private key blocks, connection strings, etc.) and replace the sensitive values with [REDACTED] while preserving the surrounding context.

broll viewer showing redacted secrets in captured output

This is on by default. You can disable it with --no-filter if you need raw output for a specific session.

Other Features

  • Session management: name, rename, annotate, tag, group, delete, and view stats
  • Export/import: share sessions as portable JSON files with teammates
  • Command extraction: pull just the commands from a session (no output) for documentation or scripting
  • Prefix matching: broll view abc matches session ID abc123... so you don't need to type full UUIDs

What's Next

I'm planning a series of detailed, deep dive videos walking through how broll's features work under the hood, going line by line through the Rust code. There's a lot of interesting stuff in here: PTY spawning, OSC escape sequence parsing, state machines for command/output delimiting, multi-threaded I/O with channels, terminal resize handling with atomics, and FTS5 full-text search integration. These won't be quick overviews. Each video will be a real deep dive into the internals, so if you're into Rust or systems programming, I think you'll get a lot out of them.

Some features on the roadmap: regex search, cross-session timelines, collapsible output chunks, and auto-start via shell integration so you don't even need broll start.


broll is MIT-licensed and available on crates.io and GitHub.

If you try it out, I'd love to hear your feedback. And if terminal tooling or Rust internals are your thing, follow along. More content is coming.

Top comments (0)