🎯

linkify

🎯Skill

from hopeoverture/worldbuilding-system

VibeIndex|
What it does

linkify skill from hopeoverture/worldbuilding-system

linkify

Installation

git cloneClone repository
git clone https://github.com/your-username/worldbuilding-system.git
PythonRun Python server
python scripts/linkify_world.py Eldermyr # Apply changes
PythonRun Python server
python scripts/linkify_world.py Eldermyr --dry-run # Preview changes
PythonRun Python server
python scripts/linkify_world.py Eldermyr --verbose # Detailed output
Server ConfigurationMCP server configuration block
{ "mcpServers": { "obsidian": { "command": "npx", "args": ["-y...
πŸ“– Extracted from docs: hopeoverture/worldbuilding-system
1
-
Last UpdatedJan 26, 2026

Skill Details

SKILL.md

Automatically add [[wikilinks]] to all mentions of existing entities within a file or entire world. Scans for entity names, aliases, and partial matches, then wraps them in wikilink syntax. Use when user wants to "linkify", "auto-link", "add links to existing entities", or "wikilink this file".

Overview

# Linkify Entity

Linkify: $ARGUMENTS

Overview

This skill scans an entity file and automatically wraps any mentions of existing entities in [[wikilink]] syntax. It's a focused tool that only adds links to entities that already existβ€”it does NOT create new entities.

Quick Start

```bash

# Linkify a specific entity

/linkify "Aldersgate"

# Preview changes without modifying

/linkify "Aldersgate" --dry-run

# Linkify by file path

/linkify Worlds/Eldermyr/Settlements/Aldersgate.md

# BULK: Linkify all entities in a world

/linkify --world Eldermyr

# BULK: Linkify only Characters in a world

/linkify --world Eldermyr --category Characters

# BULK: Preview bulk changes

/linkify --world Eldermyr --dry-run

```

Instructions

Step 1: Parse Arguments

Required:

  • Entity path or name

Optional Flags:

| Flag | Purpose | Default |

|------|---------|---------|

| --dry-run | Show what would be linked without making changes | false |

| --all-worlds | Search all worlds for entities, not just the source entity's world | false |

| --case-sensitive | Require exact case matching | false |

| --world [name] | BULK MODE: Process all entities in the specified world | - |

| --category [type] | With --world: only process entities in this category (Characters, Settlements, etc.) | all |

Step 2: Locate Entity & Determine World

  1. If path provided (contains / or .md):

- Read the file directly

- Extract world name from path: Worlds/[World Name]/...

  1. If name provided:

- Search Worlds/ directories for matching entity

- Try exact filename match first

- Then fuzzy match on filename and YAML name: field

- If multiple matches, list them and ask user to clarify

  1. If not found:

- List similar entities and ask for clarification

Step 3: Build Entity Index

Create a complete index of existing entities:

  1. Scan all files in Worlds/[World Name]/ recursively (or all worlds if --all-worlds)
  2. For each entity file, extract:

- Filename (without .md extension) β†’ primary name

- YAML name: field β†’ canonical name

- YAML aliases: array β†’ alternative names

  1. Build lookup dictionary (case-insensitive by default):

```

{

"Lord Varic Valdren": { path: "Characters/Lord Varic Valdren.md", canonical: "Lord Varic Valdren" },

"Varic": { path: "Characters/Lord Varic Valdren.md", canonical: "Lord Varic Valdren" },

"The Merchant Lord": { path: "Characters/Lord Varic Valdren.md", canonical: "Lord Varic Valdren" },

...

}

```

Important: Sort the lookup dictionary by name length (longest first) to ensure longer matches are found before shorter partial matches.

Step 4: Identify Content to Scan

Read the source entity file and identify sections to scan:

INCLUDE these sections:

  • Overview
  • Geography
  • History
  • Demographics
  • Government & Politics
  • Economy
  • Defense & Military
  • Notable Locations
  • Key Figures
  • Secrets
  • Plot Hooks
  • Description
  • Any custom content sections

EXCLUDE these sections:

  • YAML frontmatter (between --- markers)
  • Image Prompts section and everything after it
  • Connections section (already has wikilinks)
  • Code blocks (between ``` markers)
  • Existing wikilinks [[...]]
  • Block quotes used for image prompts (lines starting with > after Prompt:)

Step 5: Find Matches

For each entity name/alias in the index (longest first):

  1. Skip if entity is the source file itself (don't self-link)
  1. Search for the name in content:

- Use word-boundary matching to avoid partial matches within words

- Match: "Lord Varic Valdren" in "talked to Lord Varic Valdren about"

- Skip: "Lord Varic Valdren" in "[[Lord Varic Valdren]]" (already linked)

- Skip: "Stone" in "Aldric Stone" if "Aldric Stone" is a separate entity

  1. Record each match:

- Line number

- Exact text matched

- Canonical entity name (for the wikilink)

- Surrounding context (5 words before/after)

  1. Handle partial name matches:

- If "Lord Varic Valdren" exists but text says "Lord Varic", offer to link as [[Lord Varic Valdren|Lord Varic]]

- If "House Valdren" exists but text says "the Valdren house", consider display text

Step 6: Present Findings

```

=== LINKIFY ANALYSIS: [Entity Name] ===

World: [World Name]

Source: [path/to/entity.md]

Entities Indexed: X

---

MATCHES FOUND: Y

| # | Text Found | Line | Links To | Context |

|---|------------|------|----------|---------|

| 1 | Lady Serana Valdren | 121 | [[Lady Serana Valdren]] | "...wife, manages court..." |

| 2 | High Confessor Maren | 136 | [[High Confessor Maren]] | "...supporters, seeking..." |

| 3 | Sister Elspeth | 204 | [[Sister Elspeth]] | "...Abbess of the..." |

| 4 | Lord Varic | 117 | [[Lord Varic Valdren|Lord Varic]] | "...ensuring Varic holds..." |

---

PARTIAL MATCHES (display text needed):

| # | Text Found | Line | Suggested Link |

|---|------------|------|----------------|

| 1 | "the Owl" | 123 | [[The Owl|the Owl]] |

| 2 | "young Edric" | 117, 177 | [[Edric Valdren|young Edric]] |

---

AMBIGUOUS (multiple possible matches):

| # | Text Found | Line | Could Match |

|---|------------|------|-------------|

| 1 | "Edric" | 177 | [[Edric Valdren]] or [[Prince Edric the Liberator]] |

---

SUMMARY:

  • Exact matches: X
  • Partial matches: X
  • Ambiguous: X
  • Total changes: X

Options:

  1. Apply all exact matches
  2. Apply exact + partial matches
  3. Review each individually
  4. Dry run complete (--dry-run flag)

```

If --dry-run flag is set, show report and stop.

Step 7: Apply Changes

For each approved match:

  1. Build replacement text:

- Exact match: EntityName β†’ [[EntityName]]

- Partial match: PartialName β†’ [[FullEntityName|PartialName]]

  1. Apply using Edit tool:

- Process from bottom of file to top (so line numbers don't shift)

- Use precise string replacement with surrounding context for uniqueness

- Verify each replacement succeeded

  1. Handle duplicates:

- If the same entity is mentioned multiple times, link ALL occurrences

- Exception: Don't link the same name twice in the same sentence

Step 8: Validation

After applying changes:

  1. Re-read the file
  2. Verify all intended wikilinks are present
  3. Check no content was accidentally corrupted
  4. Verify wikilinks point to existing files

Step 9: Summary Report

```

=== LINKIFY COMPLETE: [Entity Name] ===

Changes Applied: X

Links Added:

  • [[Lady Serana Valdren]] (line 121)
  • [[High Confessor Maren]] (line 136)
  • [[Sister Elspeth]] (lines 204, 252)
  • [[Lord Varic Valdren|Lord Varic]] (line 117)

Skipped (ambiguous):

  • "Edric" (line 177) - multiple matches possible

---

File Updated: [path/to/entity.md]

Suggested Next Steps:

  • Review ambiguous matches manually
  • Run /audit-world to check bidirectional links
  • Use /link-entities to add reciprocal connections

```

Matching Rules

Word Boundary Matching

Only match complete words/phrases:

| Text | Entity | Match? | Reason |

|------|--------|--------|--------|

| "spoke to Lord Varic Valdren about" | Lord Varic Valdren | Yes | Complete phrase |

| "the Valdren family" | House Valdren | No | "Valdren" alone, different entity |

| "visited Aldersgate" | Aldersgate | Yes | Complete word |

| "Aldersgates" | Aldersgate | No | Different word |

| "[[Lord Varic Valdren]]" | Lord Varic Valdren | No | Already linked |

Partial Name Handling

When text contains a shorter form of an entity name:

| Text | Entity | Link Format |

|------|--------|-------------|

| "Lord Varic said" | Lord Varic Valdren | [[Lord Varic Valdren|Lord Varic]] |

| "the Owl knows" | The Owl | [[The Owl|the Owl]] |

| "young Edric" | Edric Valdren | [[Edric Valdren|young Edric]] |

Case Handling

By default (case-insensitive):

  • "lord varic valdren" matches "Lord Varic Valdren"
  • Original case is preserved in display text

With --case-sensitive:

  • Only exact case matches

Exclusion Patterns

Never link:

  • Text inside existing [[wikilinks]]
  • Text in YAML frontmatter
  • Text in code blocks
  • Text in Image Prompts section
  • The entity's own name (no self-linking)
  • Text that's part of a markdown header (# Name)
  • Text in the Connections section (manage links there separately)

Bulk Processing Mode

When --world flag is provided, the skill processes multiple entities:

Bulk Mode Workflow

  1. Scan world directory:

- List all .md files in Worlds/[World Name]/

- If --category specified, only scan that folder (e.g., Characters/)

- Exclude World Overview.md by default (use --include-overview to include)

  1. Build combined entity index:

- Same process as single-entity mode

- Index is built once and reused for all files

  1. Process each entity:

- For each file, run Steps 4-7 (Find Matches β†’ Apply Changes)

- Track cumulative statistics

  1. Batch report:

```

=== BULK LINKIFY COMPLETE: [World Name] ===

Files Processed: X

Files Modified: Y

Files Unchanged: Z

Total Links Added: N

By Category:

- Characters: X files, Y links

- Settlements: X files, Y links

- Organizations: X files, Y links

...

Skipped (ambiguous): N references across M files

Performance: X.X seconds total

```

Bulk Mode Options

```bash

# Process entire world

/linkify --world Eldermyr

# Process only one category

/linkify --world Eldermyr --category Settlements

# Dry run to preview bulk changes

/linkify --world Eldermyr --dry-run

# Process multiple categories

/linkify --world Eldermyr --category Characters --category Organizations

```

Performance Notes

For large worlds (100+ entities), bulk mode:

  • Builds the entity index once (faster than per-file)
  • Processes files in parallel where possible
  • Reports progress every 10 files
  • For very large worlds (300+), consider using scripts/linkify_world.py instead

Examples

```bash

# Basic linkify

/linkify "Aldersgate"

# Preview what would be linked

/linkify "Aldersgate" --dry-run

# Linkify checking all worlds for entities

/linkify "Aldersgate" --all-worlds

# Linkify by path

/linkify Worlds/Eldermyr/Settlements/Aldersgate.md

# Case-sensitive matching

/linkify "Lord Varic Valdren" --case-sensitive

```

Integration with Other Skills

After `/create-entity`

Run /linkify on newly created entities to link any mentioned existing entities.

Before `/audit-world`

Run /linkify on key entities to add missing links before the audit.

With `/link-entities`

  • /linkify adds wikilinks within entity content
  • /link-entities manages the Connections section relationships
  • Use together for comprehensive linking

With `/populate-entity`

  • /linkify only links to EXISTING entities
  • /populate-entity --links-only does the same thing
  • /populate-entity (full) also CREATES missing entities
  • Use /linkify when you just want to add links without creating anything

Error Handling

File not found:

```

Error: Could not find entity "[name]"

Similar entities in Worlds/:

  • [similar1]
  • [similar2]

Please specify the full path or exact name.

```

No matches found:

```

=== LINKIFY: [Entity Name] ===

No unlinked entity references found.

This file either:

  • Already has all entities properly linked
  • Contains no references to other known entities
  • References entities that don't exist yet (use /populate-entity to create them)

```

Write permission error:

```

Error: Could not write to [path]

The dry-run showed X matches. Please check file permissions.

```