README
¶
Your agents already solved this. deja finds it.

Claude Code, Codex and opencode write every conversation to local files — gigabytes of debugged problems and design decisions you can't search. deja is a zero-dependency binary that indexes those histories, retroactively, in about ten seconds.
deja indexes those histories and serves them back:
- to your agent — an MCP
recalltool, so the agent can answer "we fixed this three weeks ago — worker.py:87 leaked sessions on cancel" instead of re-debugging it; - to you — a fast CLI:
deja "connection pool exhausted".
One binary, no dependencies, everything stays on your machine.
Install
curl -fsSL https://raw.githubusercontent.com/vshulcz/deja-vu/main/install.sh | sh
or:
go install github.com/vshulcz/deja-vu/cmd/deja@latest # Go
npx @vshulcz/deja-vu "query" # npm, no install
brew install vshulcz/tap/deja-vu # Homebrew
Wire it into the agents you use (edits config, keeps a .bak):
deja install --all # or: claude-code | codex | opencode
Auto-recall (optional)
For Claude Code, deja install --auto does the normal MCP install and also adds a read-only SessionStart hook. When a session starts, Claude receives a tiny (<2KB) markdown digest of the most recent sessions for the current project, so it can remember prior fixes without being asked; if the local index is missing or stale, the hook prints nothing and startup continues.
deja install --auto
That's it. Next session, ask your agent:
have we dealt with jwt refresh rotation before? check your memory
The agent calls recall and gets back the sessions where you solved it — including ones from a different harness.
CLI
$ deja "jwt refresh token"
[claude] api · Jul 8 · 8f31c0a9 — 2 matches
login started failing after refresh token rotation; jwt kid mismatch in tests
fixed by reloading jwks cache after rotateKey and adding a clock-skew test
[codex] web · Jul 1 · b77d91e2 — 1 match
refresh token cookie needed SameSite=Lax in local callback flow
| Command | What it does |
|---|---|
deja <query> |
Search all histories. Multi-word = AND. --re for regex, --harness, --project, --since 30d, --role, --json. |
deja ctx <query> |
Compact markdown digest of the best match — pipe it into a prompt. |
deja show <id> |
Print one session, tool noise collapsed. |
deja last [n] |
Recent sessions across all harnesses. |
deja sources |
What stores were found, sizes, message counts. |
deja stats [--json] |
Shareable summary: totals, harness split, top projects, activity sparkline, longest session, busiest day. |
deja mcp |
Run the stdio MCP server (what deja install wires in). |
Context piping without MCP:
claude "Prior context: $(deja ctx 'database migration')"
Stats
deja stats renders a screenshot-ready summary entirely from the local index. Use --json for the same numbers in machine-readable form.
$ deja stats
deja stats
indexed agent work, wrapped for sharing
Sessions 1284
Messages 58391
Range 2025-08-03 → 2026-07-14
By harness
[claude] 884 sessions 42110 messages
[codex] 291 sessions 11142 messages
[opencode] 109 sessions 5139 messages
Top projects
deja/vu ################## 312
api ############ 211
web ######### 164
Last 12 months
▁▁▂▃▄▅▆▇██▇█ Aug Sep Oct Nov Dec Jan Feb Mar Apr May Jun Jul
Highlights
Longest session 642 messages · [claude] · index append race in records.bin
Busiest day 2026-07-08 · 1831 messages
MCP tools
| Tool | Arguments | Returns |
|---|---|---|
recall |
query, harness?, limit? |
Dense matching snippets, ≤4KB — cheap on context. |
recall_context |
query |
Markdown digest of the best-matching session. |
Supported harnesses
| Harness | Store | Status |
|---|---|---|
| Claude Code | ~/.claude/projects/**/*.jsonl |
✅ |
| Codex CLI | ~/.codex/sessions/** + history.jsonl |
✅ |
| opencode | ~/.local/share/opencode/opencode.db |
✅ |
| aider, Gemini CLI | — | planned |
Custom locations via DEJA_CLAUDE_ROOT, DEJA_CODEX_ROOT, DEJA_OPENCODE_DB, DEJA_INDEX_DIR.
Performance
Measured on a real corpus — 1,250+ sessions, ~3.3GB across three harnesses:
| Warm search | 7–9 ms typical, ~40 ms worst-case |
| Cold index (once) | ~10 s |
| Index size | ~2.4% of corpus |
The index is incremental: when a session file grows, only that file is re-read.
How it works
Local inverted index in ~/.cache/deja: parse JSONL/SQLite stores → redact secrets → records.bin + token buckets → manifest tracks per-file size/mtime so repeat runs only ingest what changed. The MCP server is the same index behind two tools. Details: docs/ARCHITECTURE.md.
Privacy: no network path exists in the indexing or search code. Local files in, local cache out.
Security
deja redacts secrets at ingest before writing ~/.cache/deja/index.db/records.bin. It keeps surrounding text searchable and replaces only the secret value with [redacted:<kind>].
Redacted classes: AWS access keys and AWS secret assignments, generic api_key/secret/token/passwd/password/authorization assignments with long base64/hex-ish values, bearer tokens, PEM private key blocks, GitHub/OpenAI/npm/Slack/Google provider tokens, and connection URLs with user:pass@host credentials.
deja sources reports a redacted= count from the manifest. Unsafe escape hatch: set DEJA_NO_REDACT=1 to disable ingest redaction for users who intentionally want plaintext secrets in the local index.
FAQ
Does anything leave my machine? No. There is no network code in the tool.
Are secrets stored in the index? By default, no for supported patterns: secrets are redacted before index writes. If older indexes predate redaction, v0.2.0 bumps the index version and rebuilds transparently. DEJA_NO_REDACT=1 disables this and is unsafe.
What does the auto-recall hook do? It is read-only: it only checks the warm local index for the current Claude project and returns a capped (<2KB) summary. It never builds the index from the hook, and on any error it exits successfully with no output.
How is this different from /resume or a history viewer? Those are per-harness and per-project. deja is one index across every harness and project on the machine, plus an MCP tool so the agent can search it.
How is this different from cass? cass is the kitchen-sink take on the same idea: 22 providers, Rust, optional semantic embeddings, a TUI. deja is the opposite bet — one small Go binary, pure lexical, the three harnesses I actually run, zero things to configure or download. If you want hybrid search over everything, use cass. If you want grep-fast recall that installs in ten seconds, that's deja.
And from MemPalace / Mem0 / Letta? Those are memory platforms: embeddings, vector stores, capture hooks or APIs that record sessions going forward. deja has no capture step at all — it indexes what your agents already wrote to disk, including months of history from before you installed it. They can coexist.
What about Windows? Builds exist and file locking is implemented; macOS/Linux are the tested paths today.
Can I exclude a project? Not yet — planned as --exclude. Today you can point DEJA_*_ROOT at a filtered copy.
How do I wipe everything?
deja uninstall --all
rm -rf ~/.cache/deja
Contributing
make build test lint — see CONTRIBUTING.md. Adding a harness is one parser file: docs/ARCHITECTURE.md.
License
MIT © Vladislav Shulcz