agentleFS
burakolgunburakolgun/vault-anything/skills/vault/SKILL.md

vault

Skill4 starsChanged 6 months agoMITView on GitHub

Generate an Obsidian LLM wiki vault from a project's source code and any static documents in raw/

11 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions11 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 11

    1. joelhooks/joelclaw★ 65same name
    2. G1Joshi/Agent-Skills★ 15same name
    3. kriscard/Skills★ 15same name
    4. AnYejun/blind-vault★ 12same name
    5. magnusrodseth/dotfiles★ 3same name
    6. M1hairu/skills★ 2same name
    7. TeamHelix-AI/helix★ 1same name
    8. yiyaw-lab/agent-armor★ 1same name
    9. abevz/devops-skills★ 0same name
    10. crsmithdev/aleph★ 0same name

    1 more not listed

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repositoryOne other file it gives its agents.

The file

Show its rules and text

We split this skill into the rules it gives an agent

15 rules. 0 are common, 4 are distinctive, and 11 are very specific to this project.

  • 0

    Common

    Most of the 10 edited versions we read keep these.

  • 4

    Distinctive

    This author's own choices. Worth a look.

  • 11

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Run the resolvers to get plugin and workspace paths.

    line 23
  2. Very specific:

    If $EXISTS is "true", this project has been analyzed before.

    line 44
  3. Very specific:

    If $EXISTS is "false", proceed with full analysis.

    line 48
  4. Distinctive:

    Before running the phases, use the TaskCreate tool to create a top-level task list the user can watch.

    line 52
  5. Very specific:

    If the user picked option (c) above (regenerate from existing raw/), mark tasks 1 and 2 as completed immediately (they're being skipped, …

    line 60
  6. Distinctive:

    Run the analyzer script. It scans files, detects frameworks and entry points deterministically, builds an import map, and produces batch …

    line 70
  7. Distinctive:

    Check whether a commit hash was captured:

    line 85
  8. Very specific:

    If $COMMIT_HASH is the string "null", the root isn't under git (or has no commits yet).

    line 92
  9. Very specific:

    If $FILE_COUNT is greater than 200, warn the user this may take a while and ask them to confirm before continuing.

    line 122
  10. Very specific:

    If $USER_FILES is greater than 0, report: Note: <USER_FILES> static file(s) from raw/ will be included.

    line 194
  11. Very specific:

    If $ISSUES is greater than 0:

    line 298
  12. Very specific:

    If $WARNINGS is greater than 0, list the top 5 (informational only — does not block).

    line 303
  13. Very specific:

    If the workspace is inside the project directory (default <project>/vault-anything/), suggest the user version it.

    line 327
  14. Very specific:

    Only print this if (a) the workspace lives inside the project directory and (b) the project has a .git directory.

    line 341
  15. Very specific:

    Multi-project case: if the root has no .git of its own but $SUBREPO_COUNT (from Phase 1) is greater than 0, the combined vault can't be …

    line 344

“Common” is measured: kept by at least 6 in 10 of the 10 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

/vault-anything:vault

Analyzes a project's source code and any static documents the user has placed under raw/, then generates a Karpathy-style Obsidian wiki vault where every page is self-contained and useful as either human documentation or LLM context.

Arguments

ArgumentDefaultDescription
project-dircurrent directorySource code to analyze
--workspace<project>/vault-anything/Where raw/ and vault/ are written
--langenVault page output language (must match a file in locales/)

Phase 0 — Pre-flight

Run the resolvers to get plugin and workspace paths. Save the outputs into shell variables you'll use throughout:

set -e
PLUGIN_ROOT=$(node "$CLAUDE_SKILL_DIR/resolve-plugin-root.mjs")
WORKSPACE=$(node "$PLUGIN_ROOT/skills/vault/resolve-workspace.mjs" "$@")

Parse $WORKSPACE (it's a JSON object) into shell variables with jq:

PROJECT_DIR=$(echo "$WORKSPACE"   | jq -r '.projectDir')
PROJECT_NAME=$(echo "$WORKSPACE"  | jq -r '.projectName')
WORKSPACE_DIR=$(echo "$WORKSPACE" | jq -r '.workspaceDir')
RAW_DIR=$(echo "$WORKSPACE"       | jq -r '.rawDir')
VAULT_DIR=$(echo "$WORKSPACE"     | jq -r '.vaultDir')
EXISTS=$(echo "$WORKSPACE"        | jq -r '.exists')
VAULT_LANG="en"   # parse from --lang argument if user provided one

Decision:

  • If $EXISTS is "true", this project has been analyzed before. Ask the user which path to take:
    • (a) Full re-analysis (all phases run again)
    • (b) Just update what changed → tell the user to run /vault-anything:vault-update instead, then STOP.
    • (c) Skip scan + analyze, regenerate vault from existing raw/ (jump to Phase 3).
  • If $EXISTS is "false", proceed with full analysis.

Set up progress tracking

Before running the phases, use the TaskCreate tool to create a top-level task list the user can watch. The tasks are:

  1. Phase 1: Scan project files
  2. Phase 2: Analyze files
  3. Phase 3: Cluster concepts + write skeleton
  4. Phase 4: Write pages
  5. Phase 5: Quality review

If the user picked option (c) above (regenerate from existing raw/), mark tasks 1 and 2 as completed immediately (they're being skipped, but recorded as already done so the user sees what's happening).

At the start of every subsequent phase, call TaskUpdate to mark the task in_progress. At the end of each phase, mark it completed.


Phase 1 — SCAN

Mark "Phase 1" as in_progress. Report to the user: [Phase 1/5] Scanning project files...

Run the analyzer script. It scans files, detects frameworks and entry points deterministically, builds an import map, and produces batch plans for the file-analyzer agents:

SCAN=$(node "$PLUGIN_ROOT/skills/vault/run-analyze.mjs" \
  "$PROJECT_DIR" "$RAW_DIR" "$PROJECT_NAME")

Extract counts to report to the user:

FILE_COUNT=$(echo  "$SCAN" | jq -r '.files')
LANGUAGES=$(echo   "$SCAN" | jq -r '.languages | join(", ")')
BATCH_COUNT=$(echo "$SCAN" | jq -r '.batches | length')

Check whether a commit hash was captured:

COMMIT_HASH=$(echo "$SCAN" | jq -r '.commitHash')
SUBREPO_COUNT=$(echo "$SCAN" | jq -r '.subRepos | length')

If $COMMIT_HASH is the string "null", the root isn't under git (or has no commits yet). This is fine — analysis proceeds — but mention it to the user, and distinguish the multi-project case:

  • If $SUBREPO_COUNT is greater than 0, the root is a parent directory holding several git repos (a multi-project run). The repos may be flat (parent/service) or grouped under a folder (parent/apps/sms, parent/packages/core) — both are detected, and each sub-repo's name is its path relative to the root. List them from echo "$SCAN" | jq -r '.subRepos[].name' and print:

    Note: The workspace root isn't a git repo, but <SUBREPO_COUNT> sub-repositories
    were detected (<names>). Each one's HEAD is recorded as a baseline, so
    /vault-anything:vault-update diffs each sub-repo against its own last commit
    (plus its working tree) — per-project incremental updates work. Static-file
    changes in raw/ are tracked too.
  • Otherwise (no sub-repos either) print:

    Note: No git repository was found at the root or nested within it. Code change
    detection won't be available for incremental updates; only static-file changes
    in raw/ will be tracked. If your repos are grouped deeper than 3 levels, list
    them in .vault-anything.json → "repoRoots": ["apps/sms", "packages/core"].

Now print a short plan summary for the user:

Plan
  Project:    <PROJECT_NAME> (<FILE_COUNT> files, languages: <LANGUAGES>)
  Workspace:  <WORKSPACE_DIR>
  Will dispatch <BATCH_COUNT> file-analyzer agent(s) and (after clustering) one page-writer agent per category.

If $FILE_COUNT is greater than 200, warn the user this may take a while and ask them to confirm before continuing.

Mark "Phase 1" as completed.


Phase 2 — ANALYZE FILES

Mark "Phase 2" as in_progress. Report: [Phase 2/5] Analyzing files...

For each batch (batch-1, batch-2, ...) add a sub-task under "Phase 2" so the user can watch individual batches complete. Use TaskCreate with parentId set to the Phase 2 task id, or use a single TaskUpdate that lists batch progress in the description — whichever your runtime supports.

For each batch in $SCAN.batches, dispatch a vault-anything:file-analyzer subagent via the Agent tool. Run up to 5 agents concurrently — in a single message with multiple Agent tool calls.

For each batch, the Agent tool call uses:

  • subagent_type: vault-anything:file-analyzer
  • description: Analyze batch <batchIndex>/<totalBatches>
  • prompt: described below

Iterate the batches with jq to get each batch's data:

echo "$SCAN" | jq -c '.batches[]'

For each batch, build the agent prompt. Substitute the batch-specific values into this template:

Inputs:

  • projectRoot: <PROJECT_DIR>
  • projectName: <PROJECT_NAME>
  • batchIndex: <batch.batchIndex>
  • totalBatches: <total>
  • outputPath: <RAW_DIR>/<PROJECT_NAME>/file-summaries/batch-<batchIndex>.json

Files to analyze (read each one and produce a FileSummary):

<batch.files>

Intra-batch imports (project-internal imports between files in this batch):

<batch.importData>

Cross-batch imports (files outside this batch that are referenced — for context, do not re-analyze):

<batch.crossBatchImports>

Write a JSON array of FileSummary objects to outputPath. Follow the schema and rules in your agent definition.

As each batch's subagent completes, mark its sub-task completed. After all batches complete, mark "Phase 2" as completed. Report: Phase 2 complete. <FILE_COUNT> files analyzed.


Phase 3 — CLUSTER & GENERATE SKELETON

Mark "Phase 3" as in_progress. Report: [Phase 3/5] Clustering concepts and generating vault skeleton...

GEN=$(node "$PLUGIN_ROOT/skills/vault/run-generate.mjs" \
  "$RAW_DIR" "$VAULT_DIR" "$PROJECT_NAME")

Extract counts:

PAGE_COUNT=$(echo "$GEN" | jq -r '.pagesWritten')
CATEGORIES=$(echo "$GEN" | jq -r '.categories | join(", ")')
USER_FILES=$(echo "$GEN" | jq -r '.userFiles | length')

If $USER_FILES is greater than 0, report: Note: <USER_FILES> static file(s) from raw/ will be included.

Report: <PAGE_COUNT> pages planned across categories: <CATEGORIES>

Mark "Phase 3" as completed.


Phase 4 — WRITE PAGES

Mark "Phase 4" as in_progress. Report: [Phase 4/5] Writing vault pages...

For each category in $GEN.categories, add a sub-task under "Phase 4" so the user can track progress per category (e.g. "Phase 4: write 02-Architecture (3 pages)").

Load the locale guide and the type templates. If the user asked for a language that isn't bundled, fall back to English and warn them:

LOCALE_FILE="$PLUGIN_ROOT/locales/$VAULT_LANG.md"
if [ ! -f "$LOCALE_FILE" ]; then
  echo "Note: no locale guide for '$VAULT_LANG' at $LOCALE_FILE — falling back to English." >&2
  VAULT_LANG="en"
  LOCALE_FILE="$PLUGIN_ROOT/locales/en.md"
fi
LOCALE_GUIDE=$(cat "$LOCALE_FILE")

# Load all type templates (map page type → template content)
TPL_FLOW=$(cat "$PLUGIN_ROOT/templates/flow.md")
TPL_CONCEPT=$(cat "$PLUGIN_ROOT/templates/concept.md")
TPL_CROSS=$(cat "$PLUGIN_ROOT/templates/cross-cutting.md")
TPL_REFERENCE=$(cat "$PLUGIN_ROOT/templates/reference.md")
TPL_SERVICE=$(cat "$PLUGIN_ROOT/templates/service-overview.md")
TPL_API=$(cat "$PLUGIN_ROOT/templates/api.md")        # used by type: api_index
TPL_TOPIC=$(cat "$PLUGIN_ROOT/templates/topic.md")    # used by type: topic_index
TPL_CONFIG=$(cat "$PLUGIN_ROOT/templates/config.md")  # used by type: config_index
TPL_DATA_MODEL=$(cat "$PLUGIN_ROOT/templates/data-model.md")     # used by type: data_model_index
TPL_INTEGRATIONS=$(cat "$PLUGIN_ROOT/templates/integrations.md") # used by type: integration_index
TPL_JOBS=$(cat "$PLUGIN_ROOT/templates/jobs.md")                 # used by type: job_index
TPL_PERMISSIONS=$(cat "$PLUGIN_ROOT/templates/permissions.md")   # used by type: permission_index

For each category in $GEN.categories, dispatch one vault-anything:page-writer subagent via the Agent tool. Run all categories concurrently — in a single message with multiple Agent tool calls.

For each category, get the pages that belong to it:

echo "$GEN" | jq -c --arg CAT "$CATEGORY" '.pages[] | select(.category == $CAT)'

Build the agent prompt with these substitutions. Include only the templates for page types that actually appear in this category's pages (most categories use exactly one type — flows use flow, architecture uses concept, etc.):

Inputs:

  • category: <CATEGORY>
  • vaultDir: <VAULT_DIR>/<CATEGORY>/
  • outputLanguage: <VAULT_LANG>

Templates for the page types in this category:

For type <type>:

<template content for this type, e.g. $TPL_CONCEPT>

(Include one template block per unique page type present in this category's pages.)

Locale guide:

<LOCALE_GUIDE>

wikilinkMap (use these page titles for [[wikilinks]]):

<GEN.wikilinkMap>

Pages to write (skeleton files already exist at vaultDir — read them for context, then overwrite with finished prose):

<pages for this category>

User-provided static files that contribute to this category (read these for additional context):

<userFiles relevant to this category, or empty array>

Follow the writing rules in your agent definition and the section structure in the template for each page's type. Produce one finished markdown page per entry in pages.

As each category's subagent completes, mark its sub-task completed. After all category agents finish, mark "Phase 4" as completed. Report: Phase 4 complete.


Phase 5 — REVIEW

Mark "Phase 5" as in_progress. Report: [Phase 5/5] Running quality checks...

REVIEW=$(node "$PLUGIN_ROOT/skills/vault/run-review.mjs" "$VAULT_DIR" "$RAW_DIR")

SCORE=$(echo    "$REVIEW" | jq -r '.qualityScore')
ISSUES=$(echo   "$REVIEW" | jq -r '.issues | length')
WARNINGS=$(echo "$REVIEW" | jq -r '.warnings | length')

Report Quality score: <SCORE>/100.

If $ISSUES is greater than 0:

  1. List up to 5 of them by reading $REVIEW | jq '.issues'.
  2. Attempt automatic fixes (strip backticks, add missing front matter fields).
  3. Re-run the review once to confirm.

If $WARNINGS is greater than 0, list the top 5 (informational only — does not block).

Mark "Phase 5" as completed.


Final Report

Output to the user:

✓ Vault generated

  Project:   <PROJECT_NAME>
  Workspace: <WORKSPACE_DIR>
  Pages:     <PAGE_COUNT> across <CATEGORIES>
  Quality:   <SCORE>/100

  Open in Obsidian → <VAULT_DIR>
  Run updates     → /vault-anything:vault-update <PROJECT_DIR>

Versioning suggestion

If the workspace is inside the project directory (default <project>/vault-anything/), suggest the user version it. Print:

Versioning vault-anything:
  The vault and its raw layer are designed to be committed alongside your code,
  so your team shares the same documentation. Add this single line to your
  project's .gitignore:

    vault-anything/raw/vault-review.json

  (vault-review.json changes on every run and is noise; everything else is
  meant to be committed.)

Only print this if (a) the workspace lives inside the project directory and (b) the project has a .git directory. Skip it for separate-workspace setups.

Multi-project case: if the root has no .git of its own but $SUBREPO_COUNT (from Phase 1) is greater than 0, the combined vault can't be committed to the parent because it isn't a repo. Print this instead:

Versioning this multi-project vault:
  The workspace root isn't a git repo, so the combined vault has nowhere to be
  committed. Two options:
    - git init the parent directory and commit the vault there, or
    - re-run with --workspace pointing at a dedicated docs/wiki git repo.
  vault-update tracks each sub-repo's HEAD independently, so incremental
  updates work either way.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.