Months of Claude Code sessions you thought were gone.
Claude Code prunes transcripts after about 30 days. vir reads what's still on disk, filters out the noise, and writes typed markdown notes into a folder you own (your Obsidian vault, if you have one) — retroactively, in one run. Codex sessions too.
- Open source
- MIT
- v0.26.2
Works with Claude CodeCodexObsidianMCPDataviewOllamaWeb Clipper
- multi-area-refactor-orchestration
- audit-first multi-phase delivery
- supabase-enforces-db-invariants
- trial-credit-atomicity
- schema-enumeration-stops-drops
- autonomous-test-driven-scaffolding-under-uncertainty
The problem
Three weeks ago you and Claude spent two hours working out why the Kie.ai endpoint returns 200 with the error in the body. Today it happens again, on a different project. Neither of you remembers. The session that solved it was pruned eleven days ago, and the fix exists nowhere — not in the code, not in a commit message, not in CLAUDE.md.
vir is not a memory layer your agent writes to. It reads what already happened.
How it works
A loop, not a pipeline.
Sessions become notes. Notes feed the next session. The daemon keeps it turning while you work.
Hover or tab through a step.
Why not the alternatives
Two things that don't quite work, and one that does.
- Falls short:
Agent memory stores
Built for the agent, not for you — memory in a format you never open. And they only know what happens after you install them.
- Falls short:
The transcripts themselves
Readable and yours — until Claude Code prunes them at ~30 days. And nobody greps 243 JSONL files.
- Works:
vir
Reads what's already on disk, drops the noise, writes typed notes into a graph you already look at.
The closest project to vir is Basic Memory — markdown, Obsidian, MCP, open source, and good. The difference is direction: Basic Memory has your agent write notes going forward. vir reads the sessions you already ran. They are compatible; the vaults can sit side by side.
What it writes
Anatomy of a note.
Every memory an agent-memory store keeps is for the agent. This is for you — and the agent reads it too.
You won't read four hundred of these, and you're not meant to. The agent reads them, through MCP. You read the three that matter, on the day they matter, because vir query found them or Obsidian's graph put one next to what you were already writing.
--- topic: "kie-200-error-body" aliases: - "kie-200-error-body" category: gotcha project: "growthq" session_id: 4f2a9c31-7d0e-4b8a-9c55-1e2f3a4b5c6d date: 2026-06-01T09:14:22.000Z confidence: 0.86 themes: - "kie-error-handling" - "retry-safety" branches: - "fix/blank-posts" --- Project: [[growthq]] Category: [[gotcha]] ## Summary This session debugged blank posts in growthq's image pipeline. The Kie.ai endpoint answers HTTP 200 even when generation fails: the error is only visible as `{ "code": 422, "msg": "..." }` in the body, so `res.ok` treats every failure as success and the job polls forever. ## What Was Learned - **Check the body's `code`, not the HTTP status.** The client now throws when `code !== 200` before trusting `res.ok`. - **Retry only on `code` 5xx.** 422 means the prompt was rejected and will be rejected again. ## Context The generation queue had been producing blank posts for two days. ## Related - [[retry-with-backoff-0c91be7a|retry-with-backoff]] - [[kie-ai-task-polling-loop-a83e21f0|kie-ai-task-polling-loop]]
- [[wikilinks]]
Project and category links, plus the Related section, are why the graph fills in on its own.
- confidence
How sure the classifier was. Low-confidence notes render dimmer in the vir Obsidian plugin.
- ## Related
Rebuilt from embedding neighbors, not from what the LLM guessed it should link to.
- session_id · date
Provenance. Every claim traces back to the exact session that produced it. Open the note, read the id, and you know where the sentence came from.
Inputs
Three inputs, one vault.
Agent sessions
Claude Code and Codex. Retroactive: months of existing transcripts become notes in one run — and new sessions keep flowing in.
Web articles
Clip a page to a folder, for example with Obsidian Web Clipper. vir distills it into the same vault.
PDFs and papers
Drop a paper in. It gets read, summarized, and linked next to the sessions that cited it.
Everything embeds into one vector space (built-in or Ollama, TF-IDF fallback), so vir query searches across all three.
Retrieval
Ask the vault. Or let the agent ask it.
$ vir query "how did we handle kie 200 errors" Kie.ai answers HTTP 200 even whengeneration fails; the failure only showsas code 422 in the body. Parse the bodyfirst, throw on code !== 200, and retryonly on 5xx. ──────────────────────────────────────── · gotchas/kie-200-error-body-4f2a9c31 0.81 · patterns/retry-with-backoff-0c91be7a 0.64────────────────────────────────────────sources 2 · via embedding · searched 460
Mid-session, without you asking
vir mcp exposes the vault to Claude Code or Codex as an MCP server, so the agent consults past decisions instead of rediscovering them. The gotcha above surfaces the next time Claude touches that endpoint — on any project.
Back into CLAUDE.md
vir sync-claude feeds the best notes back into your project's CLAUDE.md (and AGENTS.md), with a diff and your confirmation. Nothing is written without you seeing it first.
Lessons you keep re-learning
vir connect spots a lesson you've written down in three sessions a week or more apart and proposes it as one rule, quoting every note it came from. You review it; it reaches CLAUDE.md only with a yes for that rule. How it decides
Any agent, not just Claude Code
npx skills add djolex999/vir installs a read-only skill that has Codex, Cursor and other skill-aware agents check your notes before they work. What it does
Measured, not scored
There is no benchmark here.
Every tool in this category leads with a score — LongMemEval, LoCoMo, recall@5. None of those measure the thing that matters: whether the notes turned out to be worth reading. So here are the only numbers I have, from one machine.
- 397
- sessions. Claude Code would have pruned these. They now exist nowhere else.
- 2,012 → 460
- transcripts, notes. 1128 were subagent runs, workflow phases, or sidechains — skipped by default. 424 had nothing durable in them. 460 became notes.
Author's machine, September 2026. Yours will differ.
Your numbers
Run this before you install anything.
Mine are one machine's. Yours are the only ones that matter, and you already have them — Claude Code has been writing transcripts to your disk since the day you started.
find ~/.claude/projects -name '*.jsonl' | wc -lfind ~/.claude/projects -name '*.jsonl' -mtime +25 | wc -l- First number
Every session Claude Code still has on disk. vir reads all of them in one pass.
- Second number
The ones older than 25 days. Claude Code prunes at around 30, so that's roughly what disappears in the next five — whether or not you do anything.
Both commands only count files. They read nothing, send nothing, and change nothing. Not all of the first number becomes notes — most transcripts are subagent runs and workflow phases, and vir skips those.
What it costs you
Time and money, up front.
- 60 secondsnpm install -g, then vir init — a wizard: provider, models, vault path.Free.
- One runMonths of history become a vault.$25.85 for 297 sessions over six months, on the Anthropic API. On a Claude subscription via the claude-cli provider: no API spend at all.
- Ongoingvir schedule install registers a daemon that keeps the vault current.Median $0.004 per session, $0.14 at the 90th percentile.
vir run --dry-run estimates your own history before you commit to a full run; vir cost reports what you actually spent.
Claude Code forgets. Your vault doesn't.
Install.
npm install -g @djolex999/vir-clivir initvir runvir init is a wizard: provider, models, vault path. vir run does one pass over your sessions and writes notes. When you like the output, vir schedule install registers a daemon that keeps the vault current.
Full setup, configuration, and every command: the docs.
macOS or Linux · Node 20+ · Claude Code or Codex · Obsidian optional — the output is plain markdown either way
What actually leaves your machine
Transcripts are classified and distilled by an LLM, so their content goes to whichever provider you configure — including your Claude subscription via the claude-cli provider. Nothing else leaves the machine: no server, no account, no telemetry. Embeddings are local (built-in or Ollama) or TF-IDF.
Follow along
Solo project, shipping in public.
No mailing list, no account. Three ways to see what changes, all of them ones you already use.
- Star on GitHub
15 so far. Where the code, the issues, and the roadmap live.
- Watch releases
GitHub → Watch → Custom → Releases. One notification per version, nothing else.
- Subscribe by RSS
virwiki.dev/changelog.xml— every release note, in your reader.