| name | wiki-query |
| description | Answer questions from the user's configured Obsidian LLM Wiki vault, grounded only in the wiki's own pages, with interoperable Obsidian [[wiki-link]] citations and a ## References section. Use when the user asks to query or ask their wiki / knowledge base — e.g. "ask my wiki about X", "what does my wiki say about …", "query the wiki about …", "search my LLM wiki for …". Do NOT use for general questions that are not about the user's configured wiki; this skill only ever answers from on-disk wiki content and never writes to the vault. |
wiki-query
Answer a question against the user's Obsidian LLM Wiki vault on disk. You are
read-only and grounded only in wiki content, and your output must be
byte-compatible with the wiki produced by obsidian-llm-wiki, so the
user can run that plugin and this skill against the same vault interchangeably.
Follow the steps in order. Do not skip Step 1 or Step 2 — they decide whether you
can answer at all.
Interop contract (reproduce these exactly)
These are the fixed conventions of the wiki format. Consume them on the way in and
reproduce them on the way out.
- Vault layout:
<vaultPath>/<wikiFolder>/index.md plus
<wikiFolder>/{entities,concepts,sources}/<basename>.md. wikiFolder defaults
to wiki but is configurable — never hardcode it.
index.md line format (the routing file):
- [[<type>/<basename>|<basename>]] \aliases: A, B` - Targets are **wiki-folder-relative**, no.md, **no wikiFolder/prefix**. Sources omit the trailing summary. Parse with this regex (mirrors the plugin'sindex-search.ts): /- [[([^]|]+)(?:|[^]]+)?]]\s*(?:`aliases:\s*([^`]+)`)?/g— capture group 1 =type/basename`, group 2 = comma-separated aliases.
- Page frontmatter:
type: entity|concept|source, aliases: [...]. Pages may
carry reviewed: true (human-curated) and generation_complete: false (an
honest stub placeholder). Bodies are free-form and section labels may be
localized — only type and aliases are guaranteed. Parse just those.
- Answer links: Obsidian double brackets with the
wikiFolder prefix:
[[<wikiFolder>/entities/<slug>]], [[<wikiFolder>/concepts/<slug>]],
[[<wikiFolder>/sources/<slug>]].
❌ No HTML <a>. ❌ No Markdown [text](url). ❌ No bare [[slug]] or
prefix-less [[entities/slug]]. The prefix is required.
## References ends every answer: one line per cited page,
[[<wikiFolder>/<type>/<slug>|Display Name]] — brief description.
- Slug / link target: prefer the page's actual basename for the link
target (Obsidian resolves links by case-insensitive basename). Only normalize a
user's phrasing to a slug (strip unsafe/CJK punctuation, spaces/dots →
-,
merge/trim -, lowercase) when fuzzy-matching their wording to candidate
files — never to rewrite an existing basename.
Step 1 — Resolve the wiki location
Find the vault. Resolve in this order and stop at the first that succeeds:
.llm-wiki.json at the project root:
{ "vaultPath": "/abs/or/relative/path", "wikiFolder": "wiki" }
vaultPath is required; wikiFolder is optional and defaults to wiki.
CLAUDE.md convention line (only if no .llm-wiki.json): grep for a line
like LLM Wiki vault: <path> (wikiFolder: <name>) and use those values.
- Inline override: if the user supplied an explicit vault path in their
message, use it for this turn.
Then validate: confirm <vaultPath>/<wikiFolder>/index.md exists and looks
like a wiki — a # Wiki Index header and/or entities / concepts / sources
sibling folders. Resolve vaultPath to an absolute path; keep wikiFolder
separate (you need both: index lines are folder-relative, answer links are
folder-prefixed).
If nothing is configured (no .llm-wiki.json, no CLAUDE.md line, no inline
path), do not guess among vaults and do not answer. Print this and stop:
No LLM Wiki vault is configured. Create a .llm-wiki.json at your project root:
{ "vaultPath": "/path/to/your/vault", "wikiFolder": "wiki" }
(wikiFolder is optional and defaults to wiki.) Then ask again.
Step 2 — Load the index map
Read <vaultPath>/<wikiFolder>/index.md.
- If it is missing, empty, or contains the empty-wiki marker
> No pages yet. Ingest sources to populate the Wiki. → tell the user the wiki
has no pages yet and that they need to ingest sources (via their Obsidian LLM
Wiki plugin) before it can be queried, then stop. Do not fabricate.
- Otherwise parse every line with the interop regex above into a list of
{ path: "<type>/<basename>", aliases: [...] }. This is your routing table —
the cheap title/alias signal — and the authoritative list of pages.
Step 3 — Retrieve candidate pages (tiered, graceful degradation)
Build a ranked set of candidate pages. Tiers B and C always run. Tier A is an
optional accelerator — its absence or failure must never prevent a correct
answer.
Tier A — qmd hybrid search (optional)
- Detect the binary:
command -v qmd. If absent, skip to Tier B.
- Check whether the vault is already a registered collection:
qmd collection list
and look for a collection whose root is <vaultPath> (its name is derived from
the vault's folder basename).
-
Already a collection → run qmd query "<the user's question>".
-
Not yet indexed → this is a one-time setup. First print a short notice:
Indexing your vault with qmd for semantic search — this is a one-time setup
that may download embedding models (~2 GB) and take a few minutes. (Skip it
anytime; I can answer without qmd.)
Then run, in order:
qmd collection add "<absolute vaultPath>"
qmd embed
qmd query "<the user's question>"
- Parse
qmd query hits — they look like
qmd://<collection>/<wikiFolder>/<type>/<slug>.md with a relevance score. Map
each back to the on-disk path <vaultPath>/<wikiFolder>/<type>/<slug>.md and add
it to the candidate set.
- On any qmd error (not installed, add/embed/query failure, offline model
download, unexpected output) → silently fall back to B + C. Never let a qmd
problem block, delay, or degrade the answer. qmd's index lives outside the vault
(
~/.cache/qmd), so indexing never writes to wiki files — the read-only
guarantee (Step 5) still holds.
Tier B — index keyword map (always)
Score each index entry against the question's terms: +3 for a hit in the
basename/title, +2 for a hit in an alias. This catches pages whose title
omits the user's wording but whose aliases carry it (e.g. a query for "LLM" finding
large-language-models via its LLM alias). Mirrors the plugin's localKeywordMatch.
Tier C — body grep (always)
Grep / rg the question's salient terms across
<vaultPath>/<wikiFolder>/{entities,concepts,sources}/*.md (include
## Mentions in Source sections). This catches body-only matches the title/alias
map misses (e.g. a query for "backpropagation" finding neural-networks via its
body).
Merge
Union the candidates from A, B, and C. Prefer pages that appear in more than one
tier. Cap the set to the top ~5–8 pages to respect the context budget.
These are candidates, not guarantees. Tier A especially will return its
nearest-neighbour pages even when the vault contains nothing on the topic (vector
search never returns "nothing"), and grep can match an incidental word. Whether a
candidate actually answers the question is decided in Step 5 after you read it — an
off-topic candidate must lead to the honest "not covered" response, not a stretched
answer.
Step 4 — Read the top pages
Read each of the top ~5–8 candidate pages fully (do not use limit/offset —
you need the whole page to answer faithfully and cite accurately).
- Skip
generation_complete: false stubs — they are low-signal placeholders;
do not quote them or cite them as substantive answers.
- For an unusually large page, truncate the body you load (a
MAX_PAGE_CONTENT_CHARS-
style guard, e.g. ~8 000 chars) so retrieval stays bounded on large vaults.
Step 5 — Answer (grounded + interoperable)
Write the answer only from the pages you loaded plus the index summaries.
- Language: reply in the same language as the user's question (link targets
are language-independent — never translate a basename or slug).
- Citations: link cited pages inline with the exact convention —
[[<wikiFolder>/<type>/<slug>]], prefix required, no HTML, no [text](url),
no bare [[slug]].
- References: end with a
## References section, one line per cited page:
[[<wikiFolder>/<type>/<slug>|Display Name]] — brief description.
- No answer in the wiki? If the loaded content does not actually address the
question, say plainly that the wiki does not cover this topic and suggest
ingesting relevant sources. Invent no facts and no citations — a confident
wrong answer is worse than an honest gap.
- Read-only: answering performs no writes to the vault — you never create,
edit, delete, or reformat any wiki file. (Tier A's qmd index is separate, outside
the vault.)
- Follow-ups: for a question that depends on the previous turn, use the
conversation context plus a fresh Step 3 retrieval for the new topic — the
same grounding and citation rules apply every turn.