linkify
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
# 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
-
If path provided (contains
/or.md):- Read the file directly
- Extract world name from path:
Worlds/[World Name]/...
-
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
- Search
-
If not found:
- List similar entities and ask for clarification
Step 3: Build Entity Index
Create a complete index of existing entities:
- Scan all files in
Worlds/[World Name]/recursively (or all worlds if--all-worlds) - For each entity file, extract:
- Filename (without .md extension) → primary name
- YAML
name:field → canonical name - YAML
aliases:array → alternative names
- 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):
-
Skip if entity is the source file itself (don't self-link)
-
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
-
Record each match:
- Line number
- Exact text matched
- Canonical entity name (for the wikilink)
- Surrounding context (5 words before/after)
-
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
- If "Lord Varic Valdren" exists but text says "Lord Varic", offer to link as
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:
-
Build replacement text:
- Exact match:
EntityName→[[EntityName]] - Partial match:
PartialName→[[FullEntityName|PartialName]]
- Exact match:
-
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
-
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:
- Re-read the file
- Verify all intended wikilinks are present
- Check no content was accidentally corrupted
- 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 |
| "the Owl knows" | The Owl | `[[The Owl |
| "young Edric" | Edric Valdren | `[[Edric Valdren |
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
-
Scan world directory:
- List all
.mdfiles inWorlds/[World Name]/ - If
--categoryspecified, only scan that folder (e.g.,Characters/) - Exclude
World Overview.mdby default (use--include-overviewto include)
- List all
-
Build combined entity index:
- Same process as single-entity mode
- Index is built once and reused for all files
-
Process each entity:
- For each file, run Steps 4-7 (Find Matches → Apply Changes)
- Track cumulative statistics
-
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
# 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.pyinstead
Examples
# 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
/linkifyadds wikilinks within entity content/link-entitiesmanages the Connections section relationships- Use together for comprehensive linking
With /populate-entity
/linkifyonly links to EXISTING entities/populate-entity --links-onlydoes the same thing/populate-entity(full) also CREATES missing entities- Use
/linkifywhen 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.
More from hopeoverture/worldbuilding-system
create-world
Create a new worldbuilding project with full folder structure. Use when the user wants to start a new world, campaign setting, or fantasy setting like "create a world called Eldoria".
3generate-world
Generate an entire world with interconnected entities. Creates 80-120 entities including continents, regions, settlements, NPCs, organizations, history, and more. Use when the user wants a complete world generated automatically.
3validate-template
Validate a template or entity file has all required sections, YAML fields, and follows the worldbuilding system conventions. Use when creating new templates or checking if entities are properly structured.
3create-template
Create a new worldbuilding template for the Obsidian vault. Use when the user wants to add a new entity type template like "tavern template", "spell template", or "dungeon template".
2populate-entity
Scan an entity file to identify mentions of people, places, organizations, and other entities in the text. Creates missing entities using appropriate templates and adds wikilinks. Use when user wants to "populate", "fill out", "create linked entities", or "auto-generate connections" for an entity.
2random-encounter
Generate random encounters appropriate for a location, party level, or situation. Creates combat, social, or exploration encounters using existing world entities. Use when user wants "random encounter", "encounter table", or "what happens at [location]".
2