Rust · open-source · VibeTrail

Linking ripgrep into Your App: Index-Free Full-Text Search in VibeTrail

No database, no index--just compile the grep engine straight into a Rust app.

VibeTrail is a coding agent session browser I open-sourced: tools like Claude Code and Codex scatter session history across their own local directories in mutually incompatible formats, and their built-in resume lists only show the last few entries. VibeTrail unifies them into one interface you can browse, search, and resume with a single click. Rust + Tauri, a macOS app plus a vibetrail CLI, Apache 2.0.

Design constraint: no state

I set one rule from the first version: no database, no index, no background process, no file watching. The session files are already on disk–just read them on demand.

The benefits are concrete: no index means the entire “stale index” bug class doesn’t exist; no background process means no guilt about resource usage; delete the app and it leaves nothing behind. The cost is that search has to be fast enough–and that’s where ripgrep comes in.

Using ripgrep as a library

Most people treat ripgrep as a command-line tool, but its author split the engine into a set of standalone crates: grep-searcher, grep-regex, grep-matcher. You can reference them straight from Cargo.toml and compile the search engine into your own binary:

  • Users don’t need rg installed, and you don’t have to bundle an external binary and stitch arguments together;
  • Results come back as structured callbacks instead of stdout text–line numbers, offsets, and match ranges are right there;
  • You inherit ripgrep’s full performance dividend: searching sessions across the entire library feels instant.

Every format has its own quirks

The provider abstraction is where the real work in this project lives. Onboarding each tool means reverse-engineering its storage:

  • Claude Code: JSONL, one message per line, with sub-agent sessions that have to be folded under their root session by parent-child relationship;
  • Codex: also JSONL, but newer versions use zstd compression (.jsonl.zst), and fork chains need to be merged;
  • Cursor: sessions live in the IDE’s state.vscdb (SQLite), opened strictly read-only, with two generations of storage formats to support.

Once unified, the UI and CLI see a single interface, and adding a new tool never touches the layers above.

Resume: the last mile

Finding that session from three weeks ago is only half the job; the other half is going back to continue it: VibeTrail opens a new window in Terminal, iTerm2, Ghostty, or Warp, cds to the project directory from back then, and runs the corresponding agent’s resume command. The loop is “browse, search, resume”–drop any link and this tool is just a viewer.

The code is on GitHub. Try it out and file issues.