npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@djolex999/vir-cli

v0.8.3

Published

An LLM Wiki for Claude Code, in your Obsidian vault.

Readme

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 file at karpathy/llm-wiki.md and ended his post saying: "I think there is room here for an incredible new product instead of a hacky collection of scripts."

Several open source implementations of this pattern now exist (lucasastorian/llmwiki, Pratiyush/llm-wiki, nashsu/llm_wiki among them). Each takes a different shape.

Vir is the Obsidian-native one. It treats Obsidian as the primary frontend — not just a storage location — and integrates deeply (sidebar plugin coming, dataview-compatible frontmatter, canvas integration planned). It reads AI coding session transcripts retroactively, so months of existing history become a queryable knowledge base in one run.

Karpathy's post →

Why this exists

Every Claude Code session produces patterns, gotchas, and architecture decisions. Almost all of it ends up in ~/.claude/projects/**/*.jsonl — transcripts you open once and never again. The knowledge is real; the storage is a graveyard.

Vir reads those transcripts, distills the durable knowledge into typed markdown notes in your Obsidian vault, and feeds the best of it back into your CLAUDE.md files — so every future session starts sharper than the last. It's a concrete implementation of the pattern above.

What's coming

Vir is actively developed. In the next 30–60 days:

  • Obsidian plugin v1 — sidebar, command palette, canvas integration, submitted to the community plugin marketplace
  • Multi-agent support — Codex CLI, Cursor, Aider, Cline (one per release)
  • PDF/paper ingestion — broaden beyond developer workflows

Track progress via GitHub issues or watch the repo for releases.

Quality controls

Auto-distilled notes can be wrong. The most common concern from early users: "if your distillations are wrong, Claude treats them as truth and you get worse results, not better." Fair. Vir addresses it in layers:

  • Confidence scores on every note, written into the frontmatter (confidence: 0.xx). A cheap heuristic pre-filter drops low-signal sessions before any LLM call; classification then scores what survives, and anything at or below 0.6 is dropped before the more expensive distill step. Only high-confidence notes reach the vault.
  • Opt-in CLAUDE.md sync. Nothing vir generates touches your prompt context automatically. vir sync-claude shows a diff and waits for your confirmation — you decide what reaches Claude.
  • Plain markdown output. Every note is a file in your Obsidian vault. Read it, edit it, delete it. Nothing is hidden in a compressed database you can't inspect.
  • Lint and dedupe. vir lint flags contradictions and stale notes; vir dedupe merges similar notes that have drifted apart.
  • Active learning via vir review. Walk through new distillations and approve, edit, or reject each one. Verified notes get retrieval priority over unverified ones (in vir query and the MCP server). Rejected notes are moved to .rejected/ — recoverable, not deleted.
  • MMR-diverse retrieval. Queries return notes covering different aspects of the topic, not 5 similar duplicates. The retrieval algorithm balances relevance against diversity automatically.
  • Topic synthesis via vir compose "<topic>". Embedding-searches the vault for related session notes and articles, then synthesizes them into a single topic page under topics/, with each source wikilinked so it backlinks in Obsidian's graph. --dry-run previews the sources and cost for free.
  • Cost transparency. vir run --dry-run estimates per-session cost before you spend a cent; vir cost reports the actuals (total, median, p90, top sessions) from a local ~/.vir/cost.log; and --force-model haiku|sonnet lets you calibrate quality against price. Pricing is provider-aware (Anthropic list rates + Kie's discount), so the numbers reflect your bill — not a blended guess. Kie rates are approximate; override them in config.pricing if a report looks off.
  • Reliable failures (v0.8.0). Every command now exits non-zero on failure — no more silent successes hiding broken distills. vir reconcile --dry-run reports any pre-0.8.0 sessions that landed with empty content (e.g. via the v0.7.1 Kie-200-with-body-error bug); vir reconcile retries them, bypassing the SHA-256 processed-cache for just those rows. Retries that fail again leave the row untouched so a second pass can catch them once the underlying cause is fixed. Kie 404s carrying an api_error body envelope (transient service hiccups) are now retried alongside 429/5xx.

The bet: with these controls, signal-to-noise stays high enough that the vault is a net positive. If your discipline is strong enough to maintain CLAUDE.md and lessons.md by hand, you may not need this. If — like most of us — you let those files drift after the first week, Vir catches what slips through.

How it works

Vir reads your transcripts from ~/.claude/projects/**/*.jsonl, runs each session through a cheap heuristic filter, classifies the survivors with Haiku, and distills durable knowledge with Sonnet. Before distillation it filters tool calls — preserving intent (file paths, commands, search patterns, errors, short results) while truncating large embedded content (file writes, long bash logs, big grep dumps) to keep token cost bounded (tunable via filterToolCalls). Results are written as typed notes — patterns, gotchas, decisions, tools — cross-linked with wikilinks and indexed. State lives in local SQLite; content hashes make reruns idempotent. Optional Ollama embeddings power semantic search, and an MCP server exposes the whole vault to Claude Code mid-session.

Web articles saved to a raw/ directory (e.g. via Obsidian Web Clipper) flow through a parallel pipeline with its own taxonomy — concept, technique, reference, opinion — filed under articles/ in the same vault, embedded and indexed alongside session notes, and queryable through the same MCP tools. Articles always keep their source URL in frontmatter for backlinks; distillation paraphrases and never reproduces more than a short quote.

Claude Code sessions
      ↓
     vir
      ↓
Obsidian vault
      ↓
  CLAUDE.md
      ↓
better sessions
      ↓
     ...

How Vir compares

The LLM Wiki space has grown fast. Honest comparison:

vs other LLM Wiki implementations

| | Vir | lucasastorian/llmwiki | Pratiyush/llm-wiki | nashsu/llm_wiki | | --------------------------------- | ---------------------------- | ----------------------------- | ---------------------------------------- | ------------------------- | | Language | TypeScript / Node | Python | Python | Cross-platform desktop | | Distribution | npm install -g | Local app + hosted SaaS | git clone + python | Desktop app installer | | Obsidian integration | Native (plugin v1 in dev) | Markdown output | Outputs to vault | Own UI, no Obsidian | | Input sources | Claude Code, Web Clipper (more agents coming) | PDFs, docs upload | Claude Code, Cursor, Cline, Codex, Gemini | Documents, mixed sources | | Retroactive on existing sessions | ✓ | n/a | from install forward | n/a | | MCP server | ✓ | ✓ | ✓ | ✓ | | License | MIT | open source + hosted commercial | MIT | open source |

vs Claude Code memory tools

| | Vir | claude-mem | claude-memory | mem0 | | ----------------------------------- | ---------------- | -------------------- | ------------------ | ----------------- | | Reads existing Claude Code sessions | ✓ | from install forward | from install forward | n/a | | Markdown output | ✓ | ChromaDB | LanceDB | various backends | | Setup | npm install -g | Bun + uv + Python | pnpm + LM Studio | API/cloud setup | | License | MIT | Apache 2.0 | MIT | open core + cloud |

Different tools for different needs:

  • If you want a polished cross-platform desktop app for general document knowledge bases, use lucasastorian/llmwiki or nashsu/llm_wiki.
  • If you want multi-agent support with rich entity/concept page taxonomy and don't care about Obsidian integration depth, use Pratiyush/llm-wiki.
  • If you want a heavyweight Claude Code memory plugin with real-time capture and vector storage, use claude-mem.
  • If you're building AI applications that need to remember users long-term, use mem0 (different layer entirely).
  • If you want an Obsidian-native LLM Wiki that reads your existing Claude Code sessions and is on its way to supporting multiple AI coding agents, use Vir.

Real-world results

Real output from the author's first run across 226 Claude Code sessions.

| Metric | Value | | ------------------- | ------------------------------------------------- | | Sessions scanned | 226 | | Notes distilled | 126 | | Avg confidence | 0.91 | | High signal (≥0.8) | 121 of 126 | | Projects covered | 8 projects | | Knowledge breakdown | 54 patterns · 47 decisions · 23 gotchas · 2 tools |

These numbers show Vir works at scale, not that it's uniquely capable. Other LLM Wiki implementations would produce similar results with the same input. The distinguishing question for Vir is workflow fit — does the Obsidian-native + retroactive + multi-agent positioning match how you actually work?

Example query against the distilled vault:

$ vir query "what gotchas should I know about my auth implementation"

Based on the notes, here are the key auth gotchas:

JWT dual-token setup needs silent refresh on mount — access tokens expire in 15 min. Without a mount-time refresh check, users hit 401s on first load after a break. Middleware runs before the session is hydrated — do not read session data in middleware to gate routes. Check the JWT directly from the cookie instead. Password reset tokens must be single-use and hashed at rest — storing raw tokens in the DB leaks them if the DB is compromised. Hash with bcrypt before storing, compare on redemption. OAuth callback URLs must be registered exactly — trailing slashes, http vs https, and localhost port mismatches all cause silent redirect failures with no useful error message. Logout must clear both the access token cookie and the refresh token — clearing only one leaves the session partially alive and causes confusing re-auth loops.

sources 4 · via embedding · searched 126

Prerequisites

  • macOS or Linux (systemd or cron)
  • Node.js 20+
  • Claude Code (sessions at ~/.claude/projects/)
  • Obsidian vault
  • Anthropic API key or Kie.ai API key (~72% cheaper, same models)
  • Optional: Ollama + nomic-embed-text for semantic search

Install

npm install -g @djolex999/vir-cli

Quick start

vir init                 # guided wizard: provider, models, vault, cadence,
                         # and an optional web-articles (raw/) folder
vir run                  # one pass over your sessions → notes in your vault
vir schedule install     # register the daemon (runs every 3h by default)

vir init asks whether you save web articles to a folder (e.g. Obsidian Web Clipper). Point it at that raw/ directory and Vir distills those articles into the same vault. Leave it blank to keep Vir session-only.

vir schedule install works on Linux too: systemd is preferred, with cron used as a fallback when systemctl isn't available.

Cost

Vir runs two API calls per session: a Haiku classify (cheap) and a Sonnet distill (the main cost). Cost depends on session size and your provider.

Real cost shape (verified on 226 historical sessions via Kie)

| Metric | Sonnet (current default) | Haiku (opt-in via config) | |---|---|---| | Median session | $0.07 | $0.025 | | p90 session | $0.20 | $0.07 | | Long-tail outliers (5-hour epics) | $0.25-$0.30 | $0.08-$0.10 | | 226-session backfill | ~$21 | ~$7 |

Costs assume Kie.ai pricing (~28% of Anthropic direct). Multiply by ~3.5× for Anthropic direct rates.

What drives cost

Distill output dominates. A multi-hour Claude Code epic with hundreds of tool calls and architectural decisions distills to ~4500 output tokens at $4.27/M = $0.02 just for output, plus 25-30k input tokens at $0.85/M = $0.02. Skills, tool result payloads, and code blocks compound the input side. Vir v0.7.0 ships skill-stripping that drops average distill cost 60-70% versus pre-v0.7.0 builds, but multi-hour sessions remain the long tail.

Cost controls in v0.7.0

  • vir run shows a cost estimate before any API call when more than 20 new sessions are queued. Accept with y, decline with n, skip with --yes.
  • vir cost --since 7d aggregates real (not estimated) token usage from ~/.vir/cost.log.
  • vir cost --by-session surfaces outliers for cost investigation.
  • vir cost --top 5 shows your most expensive sessions.
  • vir run --dry-run previews per-session cost projections before the live run. Estimates are recalibrated from real v0.7.0 token data and run as a rough projection; actual cost varies with session content.

Hybrid routing

Haiku is ~3× cheaper than Sonnet and captures equal-or-more concrete detail on routine and tool-heavy sessions. Calibration data shows it only misses higher-order judgment/architectural lessons on decision-heavy and very large sessions. Hybrid routing exploits that: route routine sessions to Haiku, reserve Sonnet for where it matters.

When models.distillFast is set, each session is routed after classification:

  • category === "decision"models.distill (Sonnet)
  • inputTokens > models.distillThreshold (default 100000) → models.distill
  • otherwise → models.distillFast (Haiku)

New installs (vir init) enable hybrid by default — distillFast is set to the Haiku model. Existing installs are unaffected on upgrade: with distillFast unset, models.distill is used for every session exactly as before. Opt in by adding "distillFast": "claude-haiku-4-5" (Kie) or "claude-haiku-4-5-20251001" (Anthropic) to models in ~/.vir/config.json.

vir run --force-model haiku|sonnet bypasses hybrid routing entirely and forces every session to the named model for that run — useful for A/B comparison. Force-model wins over hybrid.

To go all-cheap instead, set models.distill itself to the Haiku model (quality degrades on decision-heavy and very large sessions).

Platform support

| Platform | Daemon | Notifications | Status | | --------------- | ------------------ | ------------- | ------------ | | macOS | launchd | osascript | Stable | | Linux (systemd) | systemd user timer | notify-send | Experimental | | Linux (cron) | crontab | notify-send | Experimental | | Windows | Not supported | — | Planned |

Linux support is experimental and untestedvir schedule install prefers a systemd user timer and falls back to a crontab entry when systemd is absent. Please report issues at github.com/djolex999/vir/issues with your distro, init system, and Node version.

Commands

| Command | Cost | Description | | --------------------------- | ----- | ----------------------------------------- | | vir init | free | Interactive setup | | vir run | cheap | Process new sessions | | vir run --full | $$ | Reprocess all sessions | | vir run --rewrite-only | free | Reformat notes, no API calls | | vir run --articles-only | cheap | Distill only web articles, skip sessions | | vir run --yes | cheap | Skip cost confirmation | | vir run --dry-run | free | Estimate per-session cost, exit before LLM | | vir run --force-model <m> | cheap | Override distill model: haiku | sonnet | | vir cost | free | API cost report (total/median/p90/top) | | vir cost --since <dur> | free | Cost within a window, e.g. 7d 24h 2w | | vir cost --by-session | free | Full per-session cost distribution | | vir query "<question>" | cheap | Semantic search your vault | | vir query … --json | cheap | Machine-readable results for tooling | | vir compose "<topic>" | $$ | Synthesize a topic page from related notes | | vir compose … --dry-run | free | Preview sources + cost, exit before LLM | | vir summarize <project> | cheap | Cross-session project synthesis | | vir summarize --all | $$ | Summarize all projects | | vir lint | cheap | Find orphans, stale notes, contradictions | | vir lint --orphans | free | Orphan check only | | vir lint --stale | free | Staleness check only | | vir lint --contradictions | cheap | Contradiction check (Haiku) | | vir dedupe | cheap | Interactive duplicate detection | | vir review | free | Walk new notes: approve/edit/reject | | vir review --project <s> | free | Review one project's notes | | vir review --all | free | Re-review, including verified notes | | vir sync-claude | free | Inject top knowledge into CLAUDE.md | | vir sync-claude --dry-run | free | Preview changes, no writes | | vir sync-claude --force | free | Apply without confirmation | | vir embed | free | Generate embeddings for semantic search | | vir embed --force | free | Regenerate all embeddings | | vir schedule install | free | Register the background daemon | | vir schedule uninstall | free | Remove the background daemon | | vir status | free | Knowledge heatmap + daemon status | | vir doctor | cheap | Diagnose installation issues | | vir doctor --json | cheap | Machine-readable install/health snapshot | | vir reconcile --dry-run | free | Report sessions that silently failed pre-0.7.2 | | vir reconcile | $$ | Retry those sessions — bypasses cache for them only |

Both vir query and vir doctor accept --json for programmatic consumers (e.g. the vir-obsidian plugin). query --json emits a JSON array of results to stdout ([] when none) and, on failure, a single-line error object to stderr with empty stdout. doctor --json emits one JSON object and always exits 0 (health lives in its daemon field).

MCP server (Claude Code integration)

Vir runs as an MCP server, letting Claude Code consult your vault mid-session instead of relying on static CLAUDE.md content.

Register Vir with Claude Code:

vir mcp install

Restart Claude Code. The vault is now queryable mid-session via five tools: vir_query, vir_status, vir_recent_notes, vir_recent_articles, vir_project_summary. vir_query takes a type filter (session | article | all) so Claude can scope a search to your dev sessions or your saved articles. Human-verified notes (approved via vir review) are ranked first; pass verified_only: true to vir_query or vir_recent_notes to see only those.

To unregister:

vir mcp uninstall

Semantic search (optional)

Vir uses TF-IDF by default. For semantic search via embeddings:

brew install ollama
ollama pull nomic-embed-text
ollama serve

Then in a new terminal:

vir embed
vir query "how do I handle rate limiting in Next.js"

Falls back to TF-IDF automatically if Ollama is not running.

Vir uses MMR (Maximum Marginal Relevance) reranking to balance relevance and diversity in query results. Instead of returning 5 notes that all say similar things, you get 5 notes covering different aspects of the topic. Tunable via retrievalDiversity in config (default 0.3, range 0.0–1.0; higher = more diverse).

Config reference

Located at ~/.vir/config.json.

| Field | Default | Description | | ------------------- | --------------------------- | ---------------------------------------------------------- | | vaultPath | — | Absolute path to Obsidian vault | | outputDir | vir | Subdir inside vault | | claudeProjectsDir | ~/.claude/projects | Claude Code sessions | | cadenceHours | 3 | Daemon run frequency (hours) | | provider | anthropic | anthropic or kie | | anthropicApiKey | — | Required if provider=anthropic | | kieApiKey | — | Required if provider=kie | | filterThreshold | 0.4 | Heuristic pre-filter (0..1) | | articlesDir | (unset) | raw/ dir for web articles. Unset → article ingestion off | | distillArticles | true | Distill articles alongside sessions (needs articlesDir) | | filterToolCalls | moderate | Tool-output filtering: aggressive | moderate | off | | retrievalDiversity| 0.3 | MMR diversity (0..1): 0.0 = pure relevance, 1.0 = pure diversity | | models.classify | claude-haiku-4-5-20251001 | Classify model | | models.distill | claude-sonnet-4-6 | Distill model — the "smart" model for decision/large sessions | | models.distillFast| (unset) | Cheap model for routine sessions. Set → hybrid routing on; unset → distill used for everything | | models.distillThreshold| 100000 | Input-token ceiling above which a session is forced to distill | | pricing | (built-in) | Optional per-provider $/1M overrides (inputPer1M/outputPer1M). Anthropic defaults track list rates; Kie defaults are approximate — verify on your Kie dashboard |

Vault structure

vault/vir/
  index.md       # full catalog of every note Vir has written
  log.md         # chronological append log of each run
  patterns/      # reusable approaches worth repeating
  gotchas/       # bugs, footguns, and edge cases
  decisions/     # architecture decisions with their rationale
  tools/         # per-tool knowledge and usage notes
  articles/      # web articles distilled from your raw/ folder
  projects/      # cross-session project summaries
  archived/      # deduplicated notes (kept, never deleted)

State & logs

~/.vir/config.json   — configuration
~/.vir/vir.db        — SQLite (hashes, embeddings, content)
~/.vir/daemon.log    — daemon run log

Project status

| | | | -------------- | ----------------------------------------- | | Tests | 147 passing | | Platforms | macOS (launchd), Linux (systemd/cron) | | Node | 20+ | | First-run cost | $1–5 (Kie.ai recommended for 72% savings) | | Ongoing cost | ~$0.05 per run |

Roadmap

  • [x] Linux support (systemd timer + cron fallback) — experimental
  • [x] Active learning — vir review to approve, edit, or reject distillations, with verified notes prioritized in retrieval
  • [x] Web article ingestion — distill markdown clipped via Obsidian Web Clipper into the same vault (the LLM Wiki pivot)
  • [ ] More input sources — PDFs, code repos, images (the full LLM Wiki pattern)
  • [ ] Windows support
  • [ ] GUI installer for non-developers
  • [ ] Obsidian plugin for in-vault queries
  • [ ] Export to anchor-plugin skill format
  • [ ] Support for Cursor and other AI editors

Contributing

PRs welcome. Open an issue first for large changes. Built with TypeScript strict — run npm run build to check before submitting. See CONTRIBUTING.md for development setup and how to regenerate the demo GIF.

git clone https://github.com/djolex999/vir
cd vir
npm install
npm run build
npm test

License

MIT

Author & credits

Built by Djordje Marković / GrowthQ Lab DOO.

Vir (вир) is the Serbian word for whirlpool — the place where a river pulls everything in and concentrates it. Sessions flow in, Vir pulls out what matters, and deposits it somewhere permanent.

Inspired by Andrej Karpathy's LLM Wiki pattern and Uros Pesic's KB Brain concept.

GitHub · LinkedIn · npm · GrowthQ Lab