From llm-wiki
Manages persistent LLM wiki knowledge bases in Obsidian vaults. Handles init, ingest files/URLs, query, lint, compile via /llm-wiki:wiki or wiki commands. Detects active wiki by CLAUDE.md and wiki/ folder.
npx claudepluginhub ekadetov/llm-wiki --plugin llm-wikiThis skill uses the workspace's default tool permissions.
Persistent, compounding knowledge base inside an Obsidian vault.
Builds and maintains an LLM-curated personal knowledge base from sources like papers, articles, transcripts, and notes. Supports ingestion, querying accumulated notes, linting, auditing, and scaling.
Maintains Obsidian-based LLM-driven wiki: ingests research papers/sources, compiles knowledge, manages topics/milestones/cross-references, queries wiki, runs lint checks.
Use when compiling raw sources into the wiki, querying the knowledge base, running health checks or lint on the wiki, evolving or improving wiki coverage, or when user says 'compile', 'update the wiki', 'query', 'lint', 'health check', 'evolve', 'what's missing', or 'suggest improvements'. Also triggers on questions that should be answered from the knowledge base.
Share bugs, ideas, or general feedback.
Persistent, compounding knowledge base inside an Obsidian vault.
/llm-wiki:wiki init my-topic
/llm-wiki:wiki ingest ~/ObsidianVault/03-Resources/my-topic/raw/article.md
/llm-wiki:wiki ingest https://example.com/article
/llm-wiki:wiki query "What is X?"
/llm-wiki:wiki lint
Walk up from cwd looking for a directory containing both CLAUDE.md and a wiki/ subfolder.
cwd. Check if CLAUDE.md and wiki/ exist in the current directory.CLAUDE.md for schema."Which wiki should I use?" List available wikis by running:
ls -d ~/ObsidianVault/03-Resources/*/wiki 2>/dev/nulland presenting the parent directory names.
Reference paths used throughout this skill:
QMD="env -u BUN_INSTALL ${CLAUDE_PLUGIN_DATA}/node_modules/.bin/qmd"
MARP="${CLAUDE_PLUGIN_DATA}/node_modules/.bin/marp"
Check: Test if "${CLAUDE_PLUGIN_DATA}/node_modules/.bin/qmd" exists and is executable via Bash: test -x "${CLAUDE_PLUGIN_DATA}/node_modules/.bin/qmd".
Important: Always invoke qmd via env -u BUN_INSTALL to force Node.js runtime. If BUN_INSTALL is set in the environment, qmd runs under Bun, which uses a SQLite build without extension loading support and cannot load sqlite-vec.
query and embed operations. ALWAYS use the full path — never bare qmd.wiki/index.md manually and grepping wiki files.init <name>Create a new wiki scaffold under the Obsidian vault.
Check if wiki already exists:
If ~/ObsidianVault/03-Resources/<name>/ exists, abort with:
"Wiki '' already exists at ~/ObsidianVault/03-Resources//. Use wiki remove <name> first, or choose a different name."
Create directory structure:
mkdir -p ~/ObsidianVault/03-Resources/<name>/raw/articles
mkdir -p ~/ObsidianVault/03-Resources/<name>/raw/attachments
mkdir -p ~/ObsidianVault/03-Resources/<name>/wiki/queries
mkdir -p ~/ObsidianVault/03-Resources/<name>/outputs/reports
Write ~/ObsidianVault/03-Resources/<name>/CLAUDE.md using the CLAUDE.md template below (fill in <name>).
Write ~/ObsidianVault/03-Resources/<name>/wiki/index.md using the index.md template below.
Write ~/ObsidianVault/03-Resources/<name>/log.md using the log.md template below.
Write ~/ObsidianVault/03-Resources/<name>/.gitignore using the .gitignore template below.
Write ~/ObsidianVault/03-Resources/<name>/qmd.yml using the qmd.yml template below.
Commit to vault git:
git -C ~/ObsidianVault add "03-Resources/<name>/" && git -C ~/ObsidianVault commit -m "init: <name> wiki"
If qmd available:
"${QMD}" collection add ~/ObsidianVault/03-Resources/<name>/wiki --name <name> && "${QMD}" embed --collection <name>
Print Web Clipper setup instruction:
Obsidian Web Clipper setup:
1. Install: https://obsidian.md/clipper
2. In clipper settings, set Destination folder to:
03-Resources/<name>/raw/articles
3. Set filename template to: {{date:YYYY-MM-DD}}-{{title}}
4. After clipping, run: /llm-wiki:wiki ingest ~/ObsidianVault/03-Resources/<name>/raw/articles/<clipped-file>.md
ingest <path|url>Acquire a source and save it to the raw library. Does NOT create wiki pages — use compile for that.
Detect active wiki (see Active Wiki Detection). Read CLAUDE.md for schema.
Acquire source:
raw/ directly (not in a subdirectory), read it from there. Sources saved before the raw/articles/ convention are still valid.Classify the source as one of: article | paper | transcript | conversation | image-set.
Save to raw library: Write to raw/articles/YYYY-MM-DD-<slug>.md with frontmatter:
---
date: YYYY-MM-DD
source-type: <classification>
source-url: <original URL or file path>
title: <extracted or inferred title>
compiled: false
---
If input was a file path already in raw/, skip this step (source is already saved).
Append to log.md:
## [YYYY-MM-DD] ingest | <title>
Saved <source-type> from <source> to raw/articles/.
Commit:
git -C ~/ObsidianVault add "03-Resources/<wiki-name>/" && git -C ~/ObsidianVault commit -m "ingest: <title>"
Print: "Source saved to raw/articles/. Run wiki compile to integrate into the wiki."
compile [<path>]Read raw sources and create/update wiki pages with entity extraction and cross-references.
<path> is given: compile that specific raw source.raw/articles/ for sources without a corresponding source-summary page in wiki/, and compile those.Detect active wiki. Read CLAUDE.md for schema and templates.
Identify sources to compile:
raw/articles/. For each, check if a corresponding source-summary page exists in wiki/ (match by slug or title). Compile any source without a matching summary.For each source to compile:
a. Read the raw source content.
b. Write or update source-summary page in wiki/ using the source-summary template from CLAUDE.md. Filename: <slug>.md.
c. Entity extraction: For each mentioned entity (person, concept, event):
wiki/.concept.md or person.md).[[wikilinks]] to related pages in both directions.d. Backlink audit (CRITICAL — do not skip):
grep -rln "<new page title>" wiki/
For each file that mentions the new page title but does NOT contain [[new-page-name]]:
add a [[wikilink]] at the first mention.
Update wiki/index.md with new/updated entries under the appropriate domain heading.
Append to log.md:
## [YYYY-MM-DD] compile | <N> sources → <M> pages
Compiled <source-titles>. Created/updated M pages.
Commit:
git -C ~/ObsidianVault add "03-Resources/<wiki-name>/" && git -C ~/ObsidianVault commit -m "compile: <summary>"
If qmd available:
"${QMD}" embed --collection <name>
query <question>Answer a question using wiki knowledge, with citations.
Detect active wiki. Read CLAUDE.md.
Find relevant pages:
"${QMD}" query "<question>" --collection <name>
Parse output for candidate page paths.wiki/index.md and identify relevant pages by title/description matching.Read all relevant pages. Follow one level of [[wikilinks]] if targets look relevant to the question.
Synthesize answer with [[wikilinks]] as citations. Format rules:
marp: true frontmatter. Render with: "${MARP}" <file> -o output.htmlFile the answer to wiki/queries/<slug>.md using the query-output frontmatter schema. Always file — no prompt.
Ask: "Promote this answer to wiki/<slug>.md as a concept page? (y/n)"
wiki/queries/ to wiki/, update frontmatter status from filed to promoted, and append to log.md:
## [YYYY-MM-DD] promote | <slug>
Promoted query answer to concept page.
Append to log.md:
## [YYYY-MM-DD] query | <question-slug>
Answered question. Referenced N pages. Filed to queries/<slug>.md.
Commit:
git -C ~/ObsidianVault add "03-Resources/<wiki-name>/" && git -C ~/ObsidianVault commit -m "query: <slug>"
lintAudit wiki integrity and fix issues.
Read all files in wiki/.
Build a link graph: for each [[wikilink]] on each page, record the edge (source → target).
Run deterministic lint script if available:
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/lint-wiki.py" <wiki-root>/wiki/
Report and fix:
| Check | Action |
|---|---|
| Orphan pages (no inbound links) | List them. Suggest adding links from related pages. |
Dead links ([[wikilinks]] to nonexistent files) | Create stub pages with appropriate template. |
| Unlinked concept mentions | Scan pages for proper nouns and technical terms appearing in prose without [[wikilinks]]. If a corresponding page exists, add the wikilink at first mention. If no page exists, flag as a candidate for a new page. |
| Contradictions | Scan for [!WARNING] markers. List them. |
| Missing "Counter-Arguments and Gaps" sections | Add empty ## Counter-Arguments and Gaps section. |
| Stale pages | Flag pages with status: stale in frontmatter. |
| Index drift | Compare index.md entries vs actual files. Add missing, remove dead. |
Suggest growth opportunities: Based on the wiki's current content and the gaps found in step 4, generate:
wiki query)Write lint report to outputs/reports/YYYY-MM-DD-lint.md:
# Lint Report — YYYY-MM-DD
**Wiki:** <name> | **Issues found:** N | **Fixed:** M
## Issues
<full issue table from step 4>
## Next Steps
<growth suggestions from step 5>
Append to log.md:
## [YYYY-MM-DD] lint | N issues found, M fixed
<summary of issues>
Commit:
git -C ~/ObsidianVault commit -am "lint: YYYY-MM-DD"
remove <name>Delete a wiki and all its contents.
Resolve wiki path: ~/ObsidianVault/03-Resources/<name>/
Verify it exists. If not, abort: "Wiki '' does not exist."
Confirm with user: List the directory contents and ask "This will permanently delete the '' wiki and all its contents. Proceed? (y/n)"
Remove qmd collection (if qmd available):
"${QMD}" collection remove <name>
Remove from git and filesystem:
git -C ~/ObsidianVault rm -rf "03-Resources/<name>/" && git -C ~/ObsidianVault commit -m "remove: <name> wiki"
Confirm: "Wiki '' has been removed."
Handle these failure modes gracefully:
| Situation | Action |
|---|---|
| No active wiki found | List available wikis in ~/ObsidianVault/03-Resources/*/wiki. Suggest wiki init <name> if none exist. |
| qmd not available | Fall back to wiki/index.md for search. Warn: "qmd unavailable — using index.md fallback." |
| Network error on URL ingest | Retry once. If still failing, report the error and suggest saving content manually to raw/articles/. |
| Git commit fails | Warn: "Git commit failed: . Changes are saved but not committed." Continue with remaining steps. |
| Wiki already exists (on init) | Abort with message referencing wiki remove. |
| Raw source too large (>50KB) | Warn: "Large source detected. Entity extraction may be incomplete. Consider splitting." Proceed anyway. |
| log.md missing | Create fresh log.md from template at topic root. Warn: "log.md was missing — created a new one." |
| No uncompiled sources (on compile) | Report: "All sources are already compiled. Nothing to do." Stop. |
| qmd collection not found | Warn and continue without search indexing. |
Used by the init operation. Apply verbatim, replacing <name> with the wiki name.
# <name> Wiki Schema
## Directory Layout
- raw/ -- immutable source drops. Never edit files here.
- raw/articles/ -- text source documents (articles, papers, transcripts).
- raw/attachments/ -- images and binary attachments.
- wiki/ -- LLM-owned pages. You have full write access here.
- wiki/index.md -- catalog. Read this FIRST before opening any other page.
- wiki/queries/ -- filed query answers. Promote to wiki/ when durable.
- outputs/reports/ -- dated lint reports and other artifacts.
- log.md -- append-only operation log. Never edit existing entries.
## Entity Types and Templates
### concept.md
---
date: YYYY-MM-DD
tags: [domain]
type: concept
status: active
---
# Concept Name
<one-paragraph summary>
## Details
...
## See Also
- [[related-concept]]
## Counter-Arguments and Gaps
...
### person.md
---
date: YYYY-MM-DD
tags: [domain, person]
type: person
status: active
---
# Person Name
Role / affiliation.
## Key Contributions
...
## See Also
- [[related-concept]]
### source-summary.md
---
date: YYYY-MM-DD
tags: [domain]
type: source-summary
source-url: https://...
---
# Source Title
One-paragraph summary.
## Key Points
...
## Entities Mentioned
- [[person-or-concept]]
## Slides
To export as a Marp slide deck, add `marp: true` to frontmatter and run:
"${MARP}" wiki/<filename>.md -o output.html
### query-output.md
---
date: YYYY-MM-DD
tags: [domain]
type: query-output
question: "<original question>"
status: filed
---
# <Question as title>
<synthesized answer>
## Sources
- [[page-1]]
- [[page-2]]
## Naming Conventions
- All filenames: lowercase-kebab-case.md
- Wikilinks: [[filename-without-extension]]
- Never use standard markdown links for internal links
## Log Format
Append to log.md after every operation. Format:
## [YYYY-MM-DD] <operation> | <title>
<one-line description>
Operations: ingest | compile | query | lint | promote | remove
## Index Format
wiki/index.md is a human- and LLM-readable catalog. Format:
## Domain Name
- [[page-name]] -- one-line description (YYYY-MM-DD)
Keep entries under 80 chars. Update after every ingest.
## Cross-Reference Rules
- Every page must link to at least one other page when content warrants it
- When creating or updating a concept page, scan index.md for related entities and add [[wikilinks]]
- Flag contradictions inline: > [!WARNING] Contradiction with [[other-page]]
## Ingest Rules
1. Acquire the source (URL or file)
2. Classify the source type
3. Save to raw/articles/ with frontmatter (compiled: false)
4. Append to log.md
5. Commit
Ingest does NOT create wiki pages. Use compile for that.
## Compile Rules
1. Identify uncompiled raw sources (no matching source-summary in wiki/)
2. For each source: write source-summary, extract entities, create/update pages
3. Backlink audit: grep existing pages for mentions of new titles
4. Update wiki/index.md
5. Append to log.md
6. Commit
One source typically touches 5-15 pages. This is normal.
## Query Rules
1. Read wiki/index.md first
2. Open relevant pages
3. Synthesize answer with [[wikilinks]] as citations
4. Always file answer to wiki/queries/ (mandatory, no prompt)
5. Offer promotion to wiki/ as a concept page (y/n)
6. Append to log.md (both query and optional promote events)
7. Commit changes
## Lint Rules
Scan all pages in wiki/ and report:
- Contradictions between pages
- Orphan pages (no inbound [[links]])
- Pages with status: stale older than 90 days
- Missing Counter-Arguments and Gaps section
- Index entries pointing to missing files
After fixing, append to log.md and commit.
.DS_Store
*.sqlite
*.sqlite-wal
*.sqlite-shm
collections:
<name>:
path: ./wiki
pattern: "**/*.md"
# <name> Wiki Index
Last updated: YYYY-MM-DD
<!-- Add entries after each ingest. Format:
## Domain
- [[page-name]] -- description (YYYY-MM-DD)
-->
# <name> Wiki Log
<!-- Append only. Never edit existing entries. Format:
## [YYYY-MM-DD] ingest | Title
One-line description.
-->