A full-text search engine for your AI session history β one unified search layer over every coding-agent session, whatever assistant produced it.
Backscroll is the retrieval abstraction over your local agent sessions: it normalizes each assistant's session format behind a single index, strips machine-generated noise, and provides instant full-text search with relevance ranking β so you query what happened, not which tool wrote it where.
- Installation
- Quick Start
- Core Idea
- The Session Index
- CLI
- AI-Native
- Configuration
- Documentation
- Development
- License
Backscroll ships as a single static binary with no external dependencies. Runtime input manifests are separate user configuration files loaded from <config_dir>/backscroll/inputs/*.inputs.toml.
curl -fsSL https://raw.githubusercontent.com/pablontiv/backscroll/master/install.sh | bashDetects your platform (Linux x86_64 / macOS aarch64), installs the binary to ~/.local/bin/, and installs the shipped Claude, Pi, and OpenCode input presets into the user input config directory without overwriting existing manifests.
Windows (PowerShell):
irm https://raw.githubusercontent.com/pablontiv/backscroll/master/install.ps1 | iexInstalls the binary to %LOCALAPPDATA%\backscroll\bin\, adds it to your PATH, and installs the shipped Claude, Pi, and OpenCode input presets into %APPDATA%\backscroll\inputs\ without overwriting existing manifests. Compatible with Windows PowerShell 5.1+.
Backscroll ships Claude, Pi, and OpenCode input presets at inputs/claude.inputs.toml, inputs/pi.inputs.toml, and inputs/opencode.inputs.toml. The install scripts copy those files into the user input config directory and skip existing manifests by default; set BACKSCROLL_FORCE_INPUTS=1 only when you intentionally want to replace edited presets.
Default input config directories:
| OS | Input manifest directory |
|---|---|
| Linux | ${XDG_CONFIG_HOME:-$HOME/.config}/backscroll/inputs/ |
| macOS | $HOME/Library/Application Support/backscroll/inputs/ |
| Windows | %APPDATA%\backscroll\inputs\ |
Set BACKSCROLL_CONFIG_DIR to override the <config_dir> base; manifests are then read from $BACKSCROLL_CONFIG_DIR/backscroll/inputs/.
If you install from a source checkout, copy presets without clobbering existing files:
config_dir="${BACKSCROLL_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}}"
mkdir -p "$config_dir/backscroll/inputs"
cp -n inputs/claude.inputs.toml inputs/pi.inputs.toml inputs/opencode.inputs.toml "$config_dir/backscroll/inputs/"
backscroll validate
backscroll config$configDir = if ($env:BACKSCROLL_CONFIG_DIR) { $env:BACKSCROLL_CONFIG_DIR } else { $env:APPDATA }
$inputsDir = Join-Path $configDir "backscroll\inputs"
New-Item -ItemType Directory -Force $inputsDir | Out-Null
foreach ($name in "claude.inputs.toml", "pi.inputs.toml", "opencode.inputs.toml") {
$dest = Join-Path $inputsDir $name
if (-not (Test-Path $dest)) { Copy-Item (Join-Path "inputs" $name) $dest }
}
backscroll validate
backscroll configgo install github.com/pablontiv/backscroll/cmd/backscroll@latest# 1. Confirm global input manifests are installed and valid
backscroll validate
backscroll config
# 2. Search β find past conversations by keyword (auto-syncs)
backscroll search "migration plan"
# 3. Search by project β limit results to a specific project
backscroll search "error handling" --project "backscroll"
# 4. List recent sessions β newest first
backscroll list --order timestamp:desc --limit 10
# 4b. Search tool activity β what command ran, or what failed
backscroll search "go test ./..." --content-type tool
# 5. Read one session β get semantic snippets from a session file
backscroll read --path ~/.claude/projects/backscroll/abc123.jsonl --tail 45 --semantic
# 6. Status β check index health
backscroll statusYour coding agents produce valuable reasoning logs, but each stores them in its own format, scattered across session files with no built-in way to search across them. Backscroll is the abstraction that unifies them β making every session searchable, persistent, and fast, regardless of which assistant produced it.
- One index across all your agents β you search content, not per-tool file formats
- Tool activity is searchable β the commands that ran, the files touched, the outputs and errors they returned
- Sessions are indexed incrementally β only changed files are re-processed
- Noise is stripped automatically β system-reminders, task-notifications, command wrappers
- Search uses BM25 ranking with highlighted snippets
- Output adapts to the consumer β human-readable, JSON, or compact LLM format
Backscroll does not modify your logs. It indexes them.
Each agent stores conversations in its own format. Backscroll normalizes them behind one index via input manifests β shipped presets cover the common agent formats (JSONL and SQLite), and any source with a compatible manifest is supported.
Backscroll extracts both the conversation (user and assistant messages) and the tool activity (the serialized tool inputs β commands, file paths, args β and their outputs and errors), indexing the latter as content_type='tool' so you can search what an agent actually did. Genuine noise β system-reminders, task-notifications, command wrappers β is stripped.
Backscroll computes a SHA-256 hash for each session file. On subsequent syncs, only files whose content has changed are re-processed β syncing thousands of sessions takes seconds after the initial run.
backscroll validate
backscroll listSubagent handling is controlled by the active input manifest. The shipped Claude preset excludes subagents paths with a discovery glob, and you can edit your installed preset if you intentionally want a different corpus.
See Sync & Indexing docs for input manifests, noise filtering, and project metadata behavior. See Downstream audit integration contract for deterministic indexed-only status/list/search queries.
# Query commands β the core v2 surface
backscroll search <QUERY> [--project P] [--source TYPE] [--content-type text|code|tool] [--json] [--max-tokens N] # Full-text search
backscroll list [--project P] [--order FIELD:DIR] [--limit N] [--json] # List indexed items
backscroll read --path <PATH> [--tail N] [--semantic] # Read one session file
# Maintenance
backscroll status [--json] # Check index health and metrics
backscroll validate # Validate index integrity
backscroll rebuild # Rebuild index from source files
backscroll purge --before <DATE> # Remove indexed items older than date
backscroll config # Show installed inputs and configurationAll v2 commands produce agent-readable output by default:
# Default β tab-separated, machine-parseable
backscroll search "query terms"
# JSON β structured output for programmatic consumption
backscroll search "query terms" --json
# Pretty β human-readable formatting with highlights
backscroll search "query terms" --prettyThe --fields flag controls field density (minimal or full), and --max-tokens caps output by approximate token count. See Search docs for output shapes and flag reference.
Latest session with semantic snippets:
PATH=$(backscroll list --project <path> --order timestamp:desc --limit 1 --json | jq -r '.sessions[0].path')
backscroll read --path "$PATH" --tail 45 --semanticFind what a tool did, or an error from a command:
# Tool inputs and outputs are indexed β no need to grep raw session files
backscroll search "exit code 1" --all-projects --content-type tool
backscroll search "internal/storage/sync.go" --all-projects --content-type toolbackscroll status shows index health: files indexed, message count, projects discovered, database size, and last sync time. Auto-syncs before reporting. Use backscroll status --json for a versioned machine-readable status document; add --indexed-only to avoid auto-syncing while inspecting the current SQLite snapshot.
Backscroll is designed as a retrieval layer for AI assistants. Default output is agent-readable and compact; use --json for structured output and --pretty for human formatting.
Use --max-tokens to fit results within a context window:
# Feed search results into an LLM pipeline (default agent-readable format)
backscroll search "architecture decisions" --max-tokens 4000
# Structured output for programmatic consumption
backscroll search "migration plan" --json --fields full | jq '.snippet'
# Project-scoped retrieval
backscroll search "error handling" --project "backscroll"All output is deterministic and machine-parseable. The default format uses tab-separated values with no ANSI escape codes. Use --pretty for terminal formatting with highlights.
Backscroll separates application configuration from input configuration.
- Application config (
backscroll.toml) controls database and embedding settings. By default, Backscroll creates an index at~/.backscroll.db. - Input config (
*.inputs.toml) controls what files are ingested viabackscroll searchandbackscroll list. The canonical runtime location is<config_dir>/backscroll/inputs/*.inputs.toml, where<config_dir>is the OS config directory orBACKSCROLL_CONFIG_DIRwhen set.
Override app settings by creating ~/.config/backscroll/config.toml or backscroll.toml in the current directory:
database_path = "/home/user/.backscroll.db"
[embedding]
model_name = "all-MiniLM-L6-v2"
similarity_threshold = 0.3Environment variables are also supported:
export BACKSCROLL_DATABASE_PATH="/tmp/custom.db"Input manifests are declared as:
version = 1
[[inputs]]
id = "claude"
source = "session"
active = true
[inputs.discover]
roots = ["/home/user/.claude/projects"]
include = ["**/*.jsonl"]
exclude = ["**/subagents/**"]
[inputs.decode]
format = "claude"A manifest declares only where to find sessions (discover) and how to decode them (decode.format). Each format is handled by a dedicated reader that knows that agent's session schema β claude, pi, and opencode ship built in. The repository presets (inputs/*.inputs.toml) are examples to install into the global input directory via the install script; Backscroll does not read the repository inputs/ directory at runtime. View configured inputs with backscroll config or backscroll validate.
See Configuration docs for the full resolution order and all options.
| Topic | Description |
|---|---|
| Sync & Indexing | Incremental sync, noise filtering, project detection |
| Search Engine | BM25 ranking, output formats, token limiting |
| Indexed Path Lookup | DB-backed lookup using search_items.source_path |
| Configuration | Config resolution, TOML format, environment variables |
| Generic Input Contract | Global *.inputs.toml contract for provider-neutral ingestion |
| Session Search Research | Feasibility study: axioms, evidence tables, capabilities matrix |
just check # gofmt --check + go vet
just test # Run all tests
just fmt # Auto-format code (gofmt -w)
just build # Build binary
just coverage-summary # Go test coverage report
just audit # go mod verifyThe versioned hooks in .githooks/ are not active until you point git at them:
git config core.hooksPath .githooksWithout this, git uses .git/hooks/ (samples only) and every push silently skips:
- the binary rebuild + install into
$HOME/.local/bin/backscroll(so your installed CLI stays stale vs. the pushed code), - the
just coverage-checkgate, and - the CLAUDE.md / docs-update validation.
Once activated, pre-push runs those gates and reinstalls the binary, skill, and input presets on every push; post-merge reinstalls after a git pull/merge. Verify a hook actually fired by running the command you changed from the PATH binary β go build reports version dev (the release version is injected by CI), so confirm by behavior, not the version string.
Commits follow Conventional Commits (type(scope): description).
PolyForm Noncommercial 1.0.0 β free for non-commercial use.