
Cross Linker
Automatically create cross-links between Obsidian notes.
Install
npx skills add https://github.com/ar9av/obsidian-wiki --skill cross-linkerWhat is this skill?
- Obsidian cross-linking
- Note graph
- Knowledge base
Adoption & trust: 2.3k installs on skills.sh; 1.8k GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Lark Doclarksuite/cli
Lark Wikilarksuite/cli
Opensource Guide Coachxixu-me/skills
Readme I18nxixu-me/skills
Doc Coauthoringanthropics/skills
Obsidian Markdownkepano/obsidian-skills
Journey fit
Common Questions / FAQ
Is Cross Linker safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Cross Linker
# Cross-Linker — Automated Wiki Cross-Referencing You are weaving the wiki's knowledge graph tighter by finding and inserting missing `[[wikilinks]]` between pages that should reference each other but currently don't. **Follow the Retrieval Primitives table in `llm-wiki/SKILL.md`.** Build the registry in Step 1 by grepping frontmatter only (not full pages). Reserve full `Read` for the unlinked-mention detection pass, and even there, only read pages whose summaries/titles make them plausible link targets. Blind full-vault reads are what this framework exists to avoid. ## Before You Start 1. **Resolve config** — follow the Config Resolution Protocol in `llm-wiki/SKILL.md` (walk up CWD for `.env` → `~/.obsidian-wiki/config` → prompt setup). This gives `OBSIDIAN_VAULT_PATH` and `OBSIDIAN_LINK_FORMAT` (default: `wikilink`). 2. Read `index.md` to get the full inventory of pages and their one-line descriptions 3. Skim `log.md` to see what was recently ingested (focus linking effort on new pages) When inserting links in Step 4, apply the link format from `llm-wiki/SKILL.md` (Link Format section) using the `OBSIDIAN_LINK_FORMAT` value. When `OBSIDIAN_LINK_FORMAT=markdown`, compute the relative `.md` path from the **file being edited** to the target page. ## Step 1: Build the Page Registry Glob all `.md` files in the vault (excluding `_archives/`, `.obsidian/`). For each page, extract: - **Filename** (without `.md`) — this is the wikilink target - **Title** from frontmatter - **Aliases** from frontmatter (if any) - **Tags** from frontmatter - **Category** from frontmatter or directory inference - **One-line summary** — first sentence or `title` field Build a lookup table: ``` page_name → { path, title, aliases, tags, summary } ``` This is your "vocabulary" — every entry in this table is a valid wikilink target. ## Step 2: Scan for Missing Links For each page in the vault: 1. **Read the full content** 2. **Extract existing wikilinks** — find all `[[...]]` references already present 3. **Search for unlinked mentions** — check if the page's text contains any of these, without being wrapped in `[[...]]`: - Page filenames (e.g., the word "MyProject" appears but `[[projects/my-project/my-project]]` is missing) - Page titles from frontmatter - Aliases from frontmatter - Entity names, project names, concept names from the registry 4. **Check for semantic connections** — pages that share multiple tags or are in the same project directory but don't link to each other ### Matching Rules - **Case-insensitive matching** for names (e.g., "my-project" matches page `MyProject`) - **Diacritic-insensitive matching** — normalize both the page name and the body text with Unicode NFKD (decompose accented characters to base + combining marks, strip combining marks) before comparing. This ensures body text "Muller" matches page `[[entities/müller]]` and vice versa. - **Skip self-references** — a page shouldn't link to itself - **Skip common words** — don't link "the", "and", generic terms. Only match on distinctive names - **Prefer the shortest unambiguous wikilink path** — use `[[page-name]]` not `[[full/path/to/page-name]]` when the name is unique across the vault - **Don't link inside code blocks** or frontmatter - **Don't double-link** — if `[[foo]]`