https://github.com/burakolgun/vault-anything
Generate Obsidian LLM wikis from source code and static docs — a Claude Code plugin.
https://github.com/burakolgun/vault-anything
claude-code claude-code-plugin developer-tools documentation knowledge-base llm obsidian
Last synced: 7 days ago
JSON representation
Generate Obsidian LLM wikis from source code and static docs — a Claude Code plugin.
- Host: GitHub
- URL: https://github.com/burakolgun/vault-anything
- Owner: burakolgun
- License: mit
- Created: 2026-05-29T15:51:22.000Z (29 days ago)
- Default Branch: main
- Last Pushed: 2026-06-01T20:14:28.000Z (25 days ago)
- Last Synced: 2026-06-01T22:07:33.442Z (25 days ago)
- Topics: claude-code, claude-code-plugin, developer-tools, documentation, knowledge-base, llm, obsidian
- Language: JavaScript
- Homepage: https://burakolgun.github.io/vault-anything/
- Size: 200 KB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# vault-anything
Generate Obsidian LLM wikis from source code and static documents.
A Claude Code plugin that reads a codebase (and optionally accompanying meeting notes, PRDs, ADRs), then produces a self-contained Obsidian vault. Inspired by Andrej Karpathy's idea of a "wiki for LLMs": every page is independently readable, prose-based, and richly cross-linked so it works equally well as human documentation or as LLM context.
## Why?
Codebases are hard for LLMs to navigate as raw files, and hard for humans to onboard into. vault-anything sits in between: it processes the project once, distills it into prose wiki pages with wikilinks, and produces an Obsidian vault that works as either documentation or LLM context.
## How It Works
The plugin maintains two layers in a workspace directory (default: `/vault-anything/`):
- **`raw/`** — staging area. The plugin writes per-file summaries here, and you can drop static documents (meeting notes, PRDs, ADRs) into numbered folders alongside.
- **`vault/`** — the finished Obsidian wiki. Self-contained prose pages, wikilink-connected, Obsidian-ready.
A single command (`/vault-anything:vault`) runs the full pipeline. Optional manual step: drop static documents into `raw/` before running, and they will be included in the generated pages.
The generated vault is organized into a handful of categories: architecture concepts, cross-cutting concerns, and reference pages for the most important files, plus a set of **single-page indexes** that each capture one structural surface of the project — its API endpoints, messaging topics, configuration, data model, external integrations, scheduled jobs, and authorization permissions. Each index folds many entities into one scannable page rather than emitting a thin page per entity. These index pages become natural cross-service bridges when you run vault-anything across multiple related projects — a queue one service publishes to and another consumes from, or an endpoint one service exposes and another calls, ends up as a single wikilink hub.
## Installation
vault-anything isn't on a plugin marketplace yet. Clone the repo and point Claude Code at the directory:
```bash
git clone https://github.com/burakolgun/vault-anything.git
claude --plugin-dir ./vault-anything
```
Once loaded, the `/vault-anything:vault` and `/vault-anything:vault-update` skills are available in that session.
### Distribution (planned)
A community-marketplace listing is planned so the plugin can be installed directly through Claude Code. Until then, the clone + `--plugin-dir` method above is the supported path.
## Usage
### First run
From inside the project directory:
```
/vault-anything:vault
```
Or from anywhere:
```
/vault-anything:vault /path/to/project
```
To put the workspace somewhere other than `/vault-anything/` (for example, a separate documentation repo):
```
/vault-anything:vault /path/to/project --workspace /path/to/wiki-repo
```
This runs the full pipeline:
1. **Scan** — discover files, detect languages, frameworks, and entry points
2. **Analyze** — `file-analyzer` agents produce per-file summaries (one agent per batch, up to 5 concurrent)
3. **Cluster + skeleton** — group summaries into wiki page concepts, write skeleton `.md` files
4. **Write** — `page-writer` agents fill the skeleton pages with prose (one agent per category, concurrent)
5. **Review** — deterministic quality checks (broken wikilinks, missing front matter, backticks, orphans)
### Incremental updates
```
/vault-anything:vault-update # current directory
/vault-anything:vault-update /path/to/project # explicit path
```
Detects code changes via `git diff` and static-document changes via SHA256 hash, then re-analyzes the changed code files and rewrites only the affected vault pages.
Code-change detection covers both **committed** changes since the last run (`lastHash..HEAD`) and your **current uncommitted work** — tracked edits and new untracked files. You don't have to commit before running `vault-update`; pending changes are picked up too, and the plan notes how many are uncommitted. (Committing is still the recommended workflow so the vault stays in sync with a known commit.)
### Without git
vault-anything works on projects that aren't under git. In that case:
- Code change detection is unavailable — `vault-update` can't tell which source files changed between runs.
- Static-file change detection (the `raw/05-Meeting Notes/`, `raw/06-PRD/` workflow) still works normally — it relies on SHA256 hashes stored in `meta.json`, not git.
If you later run `git init` and start committing, `vault-update` will pick up the new commit hash and code change detection will start working from that point forward.
### Multi-project (a parent of several repos)
You can point vault-anything at a parent directory that holds several projects to produce one combined vault — the API and Topics indexes then bridge the services automatically (one service's handler and another's client end up on the same page). The vault's `index.md` opens with a **Projects** table listing each contributing service and its analyzed file count.
When that parent directory isn't itself a git repo but the projects under it are, vault-anything detects each sub-repository and records its current HEAD in `meta.json`. `vault-update` then diffs **each sub-repo against its own recorded baseline** plus its working tree, so a change in any service is picked up — committed changes once a baseline has been recorded (the first full run records it), and uncommitted edits immediately. Changed files map back to the pages that reference them, so only those pages regenerate.
Because the parent isn't a repo, the combined vault has nowhere to be committed. Either `git init` the parent and commit the vault there, or run with `--workspace` pointing at a dedicated docs/wiki git repo.
### Excluding files
vault-anything ignores common build/VCS directories by default (`node_modules`, `.git`, `dist`, `build`, `vendor`, `venv`, `target`, `__pycache__`, `coverage`, dot-prefixed directories like `.vscode`, `.idea`, etc.).
For project-specific excludes, create a `.vaultignore` file in the project root. See `.vaultignore.example` in this repo for the format and suggested patterns.
### Adding static documents
Drop files into any folder under `raw/` whose name starts with a **two-digit numeric prefix**, for example:
```
raw/05-Meeting Notes/2026-05-29 Auth Redesign.md
raw/06-PRD/feature-x.md
raw/07-ADR/0001-pick-postgres.md
```
The next `/vault-anything:vault-update` run will hash each new or changed file, ask Claude which existing vault pages it relates to, and rewrite those pages with the new context included. The mapping is stored in `raw/meta.json` so future updates only need to re-process the files that actually changed.
## Opening in Obsidian
Open Obsidian and choose **File → Open Vault → As an existing folder**, then point it at:
```
/vault/
```
Open only the `vault/` subdirectory, not the whole `vault-anything/` directory. The `raw/` sibling holds JSON files (file summaries, page plan, manifest) which Obsidian doesn't render — pointing Obsidian at them just clutters the file tree.
The plugin pre-populates `vault/.obsidian/` with sensible defaults (graph view enabled, tags shown, orphans visible).
## Vault Output
```
vault/
├── .obsidian/ # Obsidian config (graph view + app settings)
├── index.md # Map of Content (+ Projects table in multi-project vaults)
├── 01-Flows/ # End-to-end flows (only if .vault-anything.json defines flows)
├── 02-Architecture/ # Architecture concept pages (auto-derived from tags)
├── 03-Cross-Cutting/ # Cross-cutting concerns (monitoring, security, CI/CD, etc.)
├── 04-Reference/ # Importance-ranked file reference pages
├── 05-API/ # API endpoints the project serves or calls (synchronous surface)
├── 06-Topics/ # Messaging entities: queues, topics, exchanges, channels, streams (async surface)
├── 07-Config/ # Configuration entities: env vars, feature flags, constants, secrets
├── 08-Data-Model/ # Persisted data structures: tables, models, DTOs, enums
├── 09-Integrations/ # External dependencies: SaaS, internal services, infra
├── 10-Jobs/ # Scheduled & background work: cron jobs, workers, daemons
└── 11-Permissions/ # Authorization surface: roles, scopes, permission strings
```
| Category | How it's populated |
|----------|-------------------|
| `01-Flows/` | Opt-in via `.vault-anything.json` (see [Configuration](#configuration)). You define flows (keywords + tags) and the clustering step matches them against file summaries. |
| `02-Architecture/` | Auto-derived from tag co-occurrence patterns (authentication, messaging, data layer, email, HTTP API, etc.). A page is produced when at least two files share the concept's tag set. |
| `03-Cross-Cutting/` | Same as architecture but for tags that cut across the codebase: monitoring, error handling, security, containerization, CI/CD. |
| `04-Reference/` | Selected by **multi-signal importance scoring** — fan-in, tag diversity, exported symbols, an `isCore` flag set by the file-analyzer, entry-point status, and file size. Top 15% of files (capped at 25) get reference pages. |
| `05-API/` | A single `API.md` index page listing every HTTP/RPC endpoint the project serves (`handler`) or calls (`client`), detected by the file-analyzer. The synchronous counterpart to Topics. Endpoints called but not served surface as outbound dependencies, so the page doubles as a cross-service dependency map. Specific endpoints are addressable via `[[API#POST /auth/login]]`. |
| `06-Topics/` | A single `Topics.md` index page listing every messaging entity (queue, topic, exchange, channel, stream) detected by the file-analyzer. Producers and consumers are listed as wikilinks. Specific entities are addressable via `[[Topics#forgot_password]]`. |
| `07-Config/` | A single `Configuration.md` index page cataloging env vars, feature flags, shared constants, and secrets — grouped by kind, mostly as tables. Local constants used in only one file are filtered out. **Secrets never carry their actual value** — only redacted format hints. |
| `08-Data-Model/` | A single `Data Model.md` index page cataloging tables, ORM models, DTOs, and enums — with fields and relations for the file that defines each. Addressable via `[[Data Model#User]]`. |
| `09-Integrations/` | A single `Integrations.md` index page listing third-party SaaS, other internal services, infra, and notable libraries the project depends on — its outbound dependency surface. Cross-links credentials to the Configuration page. |
| `10-Jobs/` | A single `Jobs.md` index page listing cron jobs, queue workers, and scheduled tasks with their schedule and trigger. Queue-triggered workers cross-link to the Topics page. |
| `11-Permissions/` | A single `Permissions.md` index page cataloging RBAC roles, auth scopes, and permission strings — where each is declared and where it guards a route. An audit surface, cross-linked to the API page. |
## Versioning the Vault
The default workspace location is `/vault-anything/` — a **visible directory** intended to be **committed alongside your code**. Treat the vault as documentation that travels with the repo, not as throwaway cache.
### Why commit it?
- **Consistency**: file-analyzer summaries are LLM output and are not deterministic — regenerating cache locally produces slightly different summaries, which leads to different vault pages. Committing both summaries and vault ensures everyone sees the same documentation.
- **Onboarding**: new teammates clone the repo and the vault is immediately available. No need to spend tokens regenerating.
- **PR review value**: changes to architecture show up as wiki diffs alongside the code diff — reviewers can see how the documentation changes too.
- **Audit trail**: knowing exactly which summaries produced which page is useful when something looks wrong.
### What to gitignore
Add one line to your project's `.gitignore`:
```
vault-anything/raw/vault-review.json
```
That file changes on every run (timestamps, transient warnings) and adds noise. Everything else in `vault-anything/` is meant to be committed.
### When NOT to commit
For personal experiments or scratch projects where you don't need a shared documentation surface, gitignore the whole directory:
```
vault-anything/
```
The plugin still works the same way — only your local copy gets the vault.
## Example Output
Run on a small Go async messaging service (12 source files, mostly RabbitMQ consumers and SMTP delivery):
```
vault/
├── index.md
├── 02-Architecture/
│ ├── Authentication & Authorization.md
│ ├── Messaging & Events.md
│ ├── Email & Notifications.md
│ └── Configuration.md
├── 03-Cross-Cutting/
│ └── Monitoring & Observability.md
├── 04-Reference/
│ ├── rabbit_mq.go.md
│ ├── mail_sender.go.md
│ └── main.go.md
└── 06-Topics/
└── Topics.md
```
9 pages from 12 source files. The single `Topics.md` index captures the four named RabbitMQ queues — two business queues plus their dead-letter siblings — each as a table row with the consumer file linked and the payload type identified, plus a Caveats section flagging things like auto-ack without redelivery. The reference pages cover the three load-bearing files surfaced by the importance scorer (the connection singleton, the mail sender, and the entry point). This project exposes no HTTP API, so no `05-API/` page is produced.
In a multi-project setup, the Topics index would automatically bridge services — if another project publishes to `forgot_password`, its producer file appears in that entity's Producers cell, making the cross-service contract visible in one place. The API index works the same way for synchronous calls.
## Configuration
Most users don't need to configure anything — the defaults work for most projects. For advanced use, drop a `.vault-anything.json` file in the **project root** (next to where you run the command). It's read at generate time and accepts:
- `flows` — array of `{ title, keywords, tags }` for project-specific business flows. **This is the only way to get the `01-Flows/` pages**: vault-anything never invents business flows, so a flow page is produced only when you describe one here and at least one file matches its keywords or tags.
- `concepts` — **replaces** the built-in architecture tag groups (omit to keep the defaults)
- `crossCutting` — **replaces** the built-in cross-cutting tag groups (omit to keep the defaults)
- `referenceRatio` — fraction of files to surface as reference pages (default `0.15`)
- `maxRefPages` — hard cap on reference pages (default `25`)
```json
{
"flows": [
{ "title": "Password Reset", "keywords": ["forgot_password", "reset-token"], "tags": ["authentication", "email"] }
],
"referenceRatio": 0.15
}
```
See `.vault-anything.example.json` in this repo for a fuller example. The config only takes effect on a full `/vault-anything:vault` run (adding flows is a structural change); an incremental `vault-update` keeps the existing page plan.
## Output Language
Default is **English**. Pass `--lang ` to output in another language, provided a matching guide exists at `locales/.md`. Bundled locales:
| Code | Language |
|------|----------|
| `en` | English (default) |
| `tr` | Turkish |
| `de` | German |
| `es` | Spanish |
| `fr` | French |
The locale guide controls page-writer style, tone, and conventions — not the technical schema (front matter field names, page categories, and tag taxonomies are always English). Technical terms (JWT, RabbitMQ, goroutine, middleware, etc.) stay in English regardless of the target language.
## Workspace Structure
After running, the workspace looks like this:
```
/
├── raw/
│ ├── /
│ │ ├── scan-result.json # files, languages, frameworks, entryPoints, importMap
│ │ ├── relationships.json
│ │ ├── page-plan.json # categories, pages, wikilinkMap
│ │ └── file-summaries/
│ │ └── batch-.json # one file per batch from file-analyzer
│ ├── 05-Meeting Notes/ # user-supplied (optional)
│ ├── 06-PRD/ # user-supplied (optional)
│ ├── meta.json # lastCommitHash, rawManifest hashes
│ └── vault-review.json # output of last review
└── vault/ # see "Vault Output" above
```
## Plugin Structure
```
vault-anything/
├── .claude-plugin/
│ └── plugin.json # Plugin manifest
├── package.json # Node workspace root
├── pnpm-workspace.yaml # Workspace config
├── skills/
│ ├── vault/
│ │ ├── SKILL.md # /vault-anything:vault
│ │ ├── resolve-plugin-root.mjs # locate plugin root
│ │ ├── resolve-workspace.mjs # parse args, derive paths
│ │ ├── run-analyze.mjs # Phase 1: scan + detect + batch
│ │ ├── run-generate.mjs # Phase 3: cluster + skeleton
│ │ ├── run-update.mjs # diff plan for vault-update
│ │ └── run-review.mjs # Phase 5: deterministic review
│ └── vault-update/
│ └── SKILL.md # /vault-anything:vault-update
├── agents/
│ ├── file-analyzer.md # per-file summaries + entity fields (API, topics, config, data, jobs, permissions)
│ └── page-writer.md # prose page generation
├── packages/
│ └── core/
│ ├── package.json
│ └── src/
│ ├── scan.mjs # file discovery + ignore handling
│ ├── detect-project.mjs # frameworks, entry points, import map
│ ├── compute-batches.mjs # batching for analyzer agents
│ ├── cluster-concepts.mjs # page planning, importance scoring, entity-index clustering
│ ├── write-raw.mjs # raw/ I/O (summaries, manifest)
│ ├── write-vault.mjs # vault/ I/O (skeletons, index, .obsidian)
│ ├── diff-update.mjs # git diff + raw manifest diff
│ └── vault-reviewer.mjs # deterministic quality checks
├── templates/ # Page-type templates (section structure per type)
│ ├── service-overview.md
│ ├── flow.md
│ ├── concept.md
│ ├── cross-cutting.md
│ ├── reference.md
│ ├── api.md
│ ├── topic.md
│ ├── config.md
│ ├── data-model.md
│ ├── integrations.md
│ ├── jobs.md
│ └── permissions.md
├── locales/ # Language-specific writing guides
│ ├── en.md
│ ├── tr.md
│ ├── de.md
│ ├── es.md
│ └── fr.md
├── examples/ # Tiny demo projects for smoke-testing the pipeline
│ └── hello-queue/ # 4-file Go RabbitMQ consumer
├── .github/ # Issue templates, PR template, CI workflow
├── .vaultignore.example # Sample user-side ignore patterns
├── .vault-anything.example.json # Sample project config (flows, overrides)
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
└── README.md
```
## License
MIT