Skip to content

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 your Obsidian vault — retroactively, in one run.

npm install -g @djolex999/vir-cli
See what it writes ↓

Works with Claude CodeObsidianMCPDataviewOllamaWeb Clipper

scaffold-first-approachmulti-area-refactor-orchestrationdocumentation-code-drift-at-scalesubagent-driven-developmenttest-driven-loader-implementationaudit-first multi-phase deliveryapi-provider-abstractionauth-onboarding-routingerror-handling-duplicationunused-credits-fieldmonorepo-frontend-explorationonboarding-flow-refactorserver-auth-boilerplatemulti-api-integration-architectureproject-scaffolding-audittemplate-phase-patternnextauth-jwt-flowselective-commit-strategytool-output-bounding-strategyredundant-data-fetchingflag-design-for-optional-flowintentional-accent-exceptions-during-tokenizationcost-logging-architecturellm-wiki-ingestionprogressive-disclosure-onboardingtrial-expiry-gating-without-middlewareverification-before-completionauth-boundary-preservation-in-url-forwardingollama-probe-null-breaks-inferenceappend-only audit log eliminates conflictsdefensive-null-guards-in-persistencefull-stack-exploration-workflowmonorepo-documentation-discoverymulti-template-phase-deliveryfetch-timeout-safetymock-client-per-functionbusiness-category-filteringmcp-tools-architecturemock-cleanup-strategyautonomous-test-driven-scaffolding-under-uncertaintymarkdown-pipeline-architecturethree-idioms-for-nav-statetoken-mapped-tailwind-already-compliantmass-assignment-authorizationstale-premise-trap-in-auditstrial-credit-atomicityanchor-plugin-scaffoldimage-model-swap-aspect-ratio-mappingparser-fallback-robustnessproject-scaffolding-phaseaudit-driven-scope-lock-before-buildfrontend-codebase-explorationincomplete-test-coveragedesign-system-audit-and-token-extractionagentic-loop-testinghardcoded-colors-auditmonorepo-backend-explorationcloudinary-url-validationin-memory-cache-distributed-deploymentsilent-failure class unfinishedunhandled-json-parse-errorsupdateBusiness-silent-field-nullificationcentralize-serialization-to-prevent-divergenceenv-var-consolidationfallback-field-exposure-over-fetchtype-guard-filtering-patternv1-architecture-and-sequencingautonomous-long-run-tdd-with-agent-recoverycost-recording-retry-safetymirrored-sweep-for-new-entity-typemonorepo-contract-schemasystematic-color-literal-extractiontdd-readline-mockingtest-driven-development-seamsinfra-misconfig-cascades-to-runtimemodel-reference-consistency-across-apispnpm-filter-run-keywordregex-dos-and-bcrypt-amplificationteal-misuse-in-step-indicatorsenv-setup-structureexit-code-propagation-strategymarketing-site-auth-boundarypackage-for-marketbackdrop-image-as-negative-spaceguided-flow-substeps-as-state-machinei18n-migration-workflowmonorepo-architecture-analysissse-streaming-lesson-generationtrial-expiry-soft-lock-patternkie-ai-stream-content-pathliteral-mapping-authority-over-semanticspaddle-tax-mode-bake-inpre-scaffold-statesearch-result-filteringarchitecture-overviewexplicit-required-field-choice-over-silent-defaultsthesis-as-launch-launchpadaudit-first-then-codeclient-side-only-authorization-unchangedcustom-input-componentemail-verification-flowkeyword-driven-archetype-compositionnode-output-shape-and-handle-conventionsread-only-audit-then-commit-cleanupserver-streaming-ssesvg-attribute-tokens-incompatibletdd-agent-implementationambient-audit-finds-medium-scale-gapsduplicate-subscription-preventionpre-existing-endpoint-not-validated-in-diff
110 of the 465 notes in my vault, linked as vir linked them. Hover one.465 notes · 4 types · 3549 links
Obsidian graph view of a vault distilled by vir: session notes, articles, PDFs, and topic pages, cross-linked

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.

---
topic: "Kie.ai returns 200 with an error body"
aliases:
  - "kie-ai-returns-200-with-an-error-body"
category: gotcha
project: "growthq"
session_id: 4f2a9c31
date: 2026-06-01T09:14:22.000Z
confidence: 0.86
themes:
  - kie error handling
  - retry safety
---
Project: [[growthq]]
Category: [[gotcha]]

The Kie.ai image endpoint answers HTTP 200 even when generation fails.
The failure is only visible as `{ "code": 422, "msg": "..." }` in the
body. Checking `res.ok` alone treats every failure as success and the
job polls forever.

Fix: parse the body first and throw when `code !== 200`. Retry only on
`code` 5xx — 422 means the prompt was rejected and will be rejected again.

## Related
- [[retry-with-backoff-on-idempotent-writes]]
- [[kie-ai-task-polling-loop]]
  1. [[wikilinks]]

    Project and category links, plus the Related section, are why the graph fills in on its own.

  2. confidence

    How sure the classifier was. Low-confidence notes render dimmer in the vir Obsidian plugin.

  3. ## Related

    Rebuilt from embedding neighbors, not from what the LLM guessed it should link to.

  4. 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.

Everything embeds into one vector space (Ollama optional, 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"searching 1,208 notes · 3 sourcesKie.ai answers HTTP 200 even when generation fails; thefailure only shows as code 422 in the body. Parse the bodyfirst, throw on code !== 200, and retry only on 5xx.sources  gotchas/kie-ai-returns-200-with-an-error-body-4f2a9c31.md  patterns/retry-with-backoff-on-idempotent-writes-0c91be7a.md

Mid-session, without you asking

vir mcp exposes the vault to Claude Code 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, with a diff and your confirmation. Nothing is written without you seeing it first.

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.

396
sessions. Claude Code would have pruned these. They now exist nowhere else.
1,386410
transcripts, notes. 562 were subagent runs, workflow phases, or sidechains — skipped by default. 414 had nothing durable in them. 410 became notes.

Author's machine, September 2026. Yours will differ.

What it costs you

Time and money, up front.

  1. 60 secondsnpm install -g, then vir init — a wizard: provider, models, vault path.Free.
  2. One runMonths of history become a vault.$20.38 for 295 sessions over six months, on the Anthropic API. On a Claude subscription via the claude-cli provider: no API spend at all.
  3. Ongoingvir schedule install registers a daemon that keeps the vault current.Median $0.004 per session, $0.13 at the 90th percentile.

vir cost prints this for your own history before you commit to a full run.

Claude Code forgets. Your vault doesn't.

Install.

npm install -g @djolex999/vir-cli
vir init
vir run

vir 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.

macOS or Linux · Node 20+ · Claude Code · 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 (Ollama) or TF-IDF.

The pattern

In April 2026, Andrej Karpathy described a pattern he calls the LLM Wiki: AI work that feeds back into itself through a persistent, curated, structured artifact instead of resetting at the end of every session. He published the idea as a gist and a post.

Several implementations of this pattern exist. vir is the Obsidian-native, retroactive one.