Skip to main content
ClaudeWave
Skill3.5k repo starsupdated today

wiki-query

wiki-query retrieves and answers questions against a compiled Obsidian wiki containing cross-referenced, pre-synthesized knowledge. Use this skill when you need to look up existing wiki content, understand relationships between concepts, or find supporting information, but not when you need to create new pages, modify wiki structure, or capture new findings (which require other skills like wiki-capture or wiki-quick-chat-capture).

Install in Claude Code
Copy
git clone --depth 1 https://github.com/Ar9av/obsidian-wiki /tmp/wiki-query && cp -r /tmp/wiki-query/.skills/wiki-query ~/.claude/skills/wiki-query
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Wiki Query — Knowledge Retrieval

You are answering questions against a compiled Obsidian wiki, not raw source documents. The wiki contains pre-synthesized, cross-referenced knowledge.

## This skill is READ-ONLY

`wiki-query` answers questions. It MUST NOT create or modify any wiki content. The ONLY write it may perform is the single Step 6 append to `log.md`.

Never, even when a change seems obviously helpful:
- create or edit pages under `concepts/`, `entities/`, `skills/`, `references/`, `synthesis/`, `journal/`, or `projects/`
- modify `index.md`, `hot.md`, `_insights.md`, or `.manifest.json`

If the user's message contains a new finding, an action request ("save this", "ban X", "record that"), or anything implying a change, **do not perform it.** Answer the question, PROPOSE the change, and route the user to the right skill:
- quick note / gotcha → `wiki-capture --quick`
- a full new page → `wiki-capture`
- a project-knowledge sync → `wiki-update`

## Before You Start

1. **Resolve config** — follow the Config Resolution Protocol in `llm-wiki/SKILL.md` (inline `@name` override → walk up CWD for `.env` → global config → prompt setup). For cross-project queries without `@name`, prefer the global config when present, even if it is a symlink to the vault `.env`. This gives `OBSIDIAN_VAULT_PATH` and any QMD variables. Works from any project directory.
2. **Load QMD settings from the resolved config** before deciding retrieval strategy. If `QMD_WIKI_COLLECTION` is set, treat QMD as available subject only to transport/tool checks below. If it is empty or unset, say briefly why QMD is being skipped before using grep/page reads.
3. If `$OBSIDIAN_VAULT_PATH/hot.md` exists, read it first — it gives you instant context on recent activity. If the user's question is about something ingested recently, hot.md may answer it before you even open `index.md`.
4. Read `$OBSIDIAN_VAULT_PATH/index.md` to understand the wiki's scope and structure

## Visibility Filter (optional)

By default, **all pages are returned** regardless of visibility tags. This preserves existing behavior — nothing changes unless the user asks for it.

If the user's query includes phrases like **"public only"**, **"user-facing"**, **"no internal content"**, **"as a user would see it"**, or **"exclude internal"**, activate **filtered mode**:

- Build a **blocked tag set**: `{visibility/internal, visibility/pii}`
- In the Index Pass (Step 2), skip any candidate whose frontmatter tags contain a blocked tag
- In Section/Full Read passes (Steps 3–4), do not read or cite any blocked page
- Synthesize the answer **only from allowed pages** — do not mention that excluded pages exist

Pages with no `visibility/` tag, or tagged `visibility/public`, are always included.

In filtered mode, note the filter in the Step 6 log entry: `mode=filtered`.

## Retrieval Protocol

**Follow the Retrieval Primitives table in `llm-wiki/SKILL.md`.** Reading is the dominant cost of this skill — use the cheapest primitive that answers the question and escalate only when it can't. Never jump straight to full-page reads.

### Step 0: GraphRAG Pre-pass (fast index query — no page reads)

Before opening any pages, query the compiled graph index:

```bash
obsidian-wiki graph-query "$OBSIDIAN_VAULT_PATH" "<question>" --pretty
```

Output fields:

- **`answer_type`**: `direct` | `path` | `list` | `gap` | `impact` | `bridges` | `hubs` | `clusters` | `surprising` — shapes what to do next. The last five are **structural intents**: the question is about the shape of the vault, and the answer comes back fully computed in `graph` (see below) with no page reads at all.
- **`graph`**: present only for structural intents — the computed answer. `null` otherwise.
- **`candidates`**: top-ranked pages by title/tag/summary match + degree, with scores and summaries
- **`should_read`**: the pages most worth opening — start here instead of speculatively reading many files
- **`path`**: for multi-hop queries, the shortest wikilink path between the two concepts
- **`god_nodes_relevant`**: hub pages related to your query terms — always useful context
- **`index_only`**: if `true`, the top candidate's summary already answers the question — skip page reads

**Structural intents** — these are answered entirely from the graph. The user's phrasing routes automatically:

| The user asks | `answer_type` | `graph` contains |
|---|---|---|
| "what breaks if I delete X" / "what depends on X" / "what links to X" | `impact` | `direct_dependents`, `transitive_dependents`, `total` |
| "which pages bridge my clusters" / "what would fragment my vault" | `bridges` | pages by betweenness, with `label` and `connects_labels` |
| "what's central" / "top hubs" / "my main topics" | `hubs` | pages by degree, with in/out split |
| "what clusters do I have" / "how is my wiki organised" | `clusters` | each cluster's `label`, `size`, `cohesion`, `fragmented` |
| "surprising connections" / "unexpected links" | `surprising` | cross-cluster links, rarest first |

Report the `graph` payload directly — do **not** re-derive it by reading pages. If a structural question names a page that can't be resolved, the CLI falls back to `direct` and `graph` is `null`.

**Decision tree:**

1. If `graph` is non-null → the structural answer is complete. Report it and stop; no page reads.
2. If `index_only: true` → answer directly from `candidates[0].summary`. Skip Steps 1–4, go to Step 5.
3. If `answer_type == "path"` and `path` is non-empty → the connection is in `path`. Read only those pages.
4. Otherwise → open only `should_read` pages (not all candidates). This replaces the speculative 5–10 page reads the old flow required.

> The graph used here excludes vault bookkeeping files (`index.md`, `log.md`, `hot.md`, `_insights.md`). They link to nearly every page, so including them made any two pages look ~2 hops apart and produced meaningless `A → index → B` paths.

**Fallback** (if `obsidian-wiki` is not installed): proceed wi