Specification
Skill ID
ar9av/obsidian-wiki/wiki-import
Publisher
ar9av
Repository
obsidian-wiki
Installs
0
Files
1
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

ar9av/obsidian-wiki/wiki-importInstalls these files
  • SKILL.md

What this skill tells the agent

Wiki Import — Reconstruct Pages from an Export

You are importing a vault's knowledge into the current vault from one of two sources produced by wiki-export:

  • `graph.json` — the graph skeleton. Reconstructs page stubs (frontmatter, typed relationships, a ## Related link list — no body). Lossy.
  • OKF bundle (a wiki-export/okf/ directory) — the actual markdown files. Reconstructs full pages with their real bodies. Lossless. Use this for true vault-to-vault transfer.

Either way, the import writes pages with correct frontmatter and wikilinks, then updates all vault metadata. Step 2, Step 3 (graph only), and Step 5 are shared; Step 4 forks by source type.

Before You Start

Writing profile: Before drafting or rewriting natural-language Markdown, read and apply the Writing Profile Resolution section in llm-wiki/SKILL.md. Framework schema, provenance, safety, and operation-specific requirements take precedence. Preserve imported source prose; apply WRITING.md preferences only to newly generated metadata or stubs.

  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). This gives OBSIDIAN_VAULT_PATH.
  2. Read $OBSIDIAN_VAULT_PATH/AGENTS.md if it exists — apply any owner-specific conventions.

Step 1: Locate and Detect Source Type

Find the import source:

  • If the user provided a path argument, use it directly.
  • Otherwise auto-detect, in order: ./wiki-export/okf/ (a directory) → ./wiki-export/graph.json (a file).
  • If neither exists, ask the user for the path.

Detect the source type:

  • The path is a file ending in `.json` → graph.json import (validate below, then Step 3 + Step 4-Graph).
  • The path is a directory containing .md files with OKF frontmatter (a type: key), and/or a root index.md with okf_version → OKF bundle import (skip Step 3; go to Step 4-OKF).
  • Anything else → report what's wrong and stop.

Validate a graph.json source:

  • Must be valid JSON
  • Must have top-level keys: nodes (array), links (array), graph (object)
  • Must have at least 1 node

If validation fails, report what's wrong and stop.

Validate an OKF bundle source:

  • Must contain at least 1 non-reserved .md file (i.e. not index.md/log.md) with parseable YAML frontmatter containing a non-empty type.
  • A .md with no frontmatter or no type is skipped (with a count), not fatal — OKF consumers are permissive (OKF §9).

Show a preview before importing:

graph.json:

Import preview (graph.json — stubs)
  Source: <path>  (exported at <graph.exported_at>)
  Nodes:  N total  (concepts: A, entities: B, skills: C, references: D, ...)
  Links:  M edges  (X typed, Y untyped)
  Target: $OBSIDIAN_VAULT_PATH

OKF bundle:

Import preview (OKF bundle — full pages)
  Source: <dir>  (okf_version <ver if present>)
  Pages:  N total  (concepts: A, entities: B, skills: C, references: D, ...)
  Target: $OBSIDIAN_VAULT_PATH

Step 2: Determine Conflict Resolution Mode

Read the user's phrasing to determine mode. Default is merge.

ModeTrigger phrasesBehaviour
merge(default, no special phrasing)Existing pages: update frontmatter tags/summary/relationships and add missing wikilinks; new pages: create stub.
skip"skip existing", "don't overwrite", "only new pages"Leave existing pages completely untouched; only create pages that don't exist yet.
overwrite"overwrite", "replace existing", "force import"Replace all matched pages with freshly reconstructed stubs regardless of existing content.

Step 3: Build Internal Maps (graph.json only — skip for OKF bundles)

Before writing anything, build two maps from the links array:

Adjacency map — for each node id, collect all neighbour ids (edges in either direction):

adjacency["concepts/transformers"] = ["entities/vaswani", "concepts/lstm", ...]

Typed edge map — for each node id, collect outgoing typed edges only (typed: true):

typed_edges["concepts/transformers"] = [
  {target: "concepts/lstm", relation: "contradicts"},
  ...
]

Step 4-Graph: Reconstruct Pages from graph.json (graph.json source only)

Record counts: created = 0, skipped = 0, merged = 0.

For each node in nodes:

  1. Compute page_path = $VAULT/<node.id>.md
  2. Ensure the parent directory exists (e.g. $VAULT/concepts/)
  3. Check if the file already exists:
  • merge mode (default) + exists → read existing file, apply merge logic (see below), increment merged
  • merge mode (default) + doesn't exist → proceed to create stub, increment created
  • skip mode + exists → increment skipped, continue to next node
  • skip mode + doesn't exist → proceed to create stub, increment created
  • overwrite mode + exists → proceed to write fresh stub (overwrite), increment merged
  • overwrite mode + doesn't exist → proceed to create stub, increment created

Page template (new or overwrite)

---
title: <node.label>
category: <node.category>
tags: <node.tags as YAML list>
sources:
  - "imported from <graph.json path>"
<if node.summary exists>
summary: "<node.summary>"
</if>
<if typed_edges[node.id] is non-empty>
relationships:
<for each {target, relation} in typed_edges[node.id]>
  - target: "[[<target>]]"
    type: <relation>
</for>
</if>
lifecycle: draft
lifecycle_changed: <today YYYY-MM-DD>
base_confidence: 0.5
tier: supporting
created: <ISO timestamp>
updated: <ISO timestamp>
---

# <node.label>

<node.summary paragraph if available, else omit>

## Related

<for each neighbour in adjacency[node.id], sorted alphabetically>
<if edge is typed>
- [[<neighbour>]] — <relation>
<else>
- [[<neighbour>]]
</if>
</for>

If adjacency[node.id] is empty, omit the ## Related section entirely.

Merge logic (merge mode, existing page)

  1. Read the existing page's frontmatter.
  2. Tags: union of existing tags and node.tags (deduplicated, keep existing order, append new ones).
  3. Summary: if the existing page has no summary field and node.summary exists, add it.
  4. Relationships: union of existing relationships: entries and typed_edges[node.id] — skip entries where the same (target, type) pair already exists.
  5. Updated: set updated to the current ISO timestamp.
  6. Body: scan for a ## Related section. If it exists, append any missing wikilinks from adjacency[node.id] that aren't already linked anywhere in the body. If no ## Related section exists, append one with the missing links.
  7. Leave the rest of the body untouched.

Step 4-OKF: Reconstruct Pages from an OKF bundle (OKF source only)

Record counts: created = 0, skipped = 0, merged = 0, unparseable = 0.

Walk the bundle directory tree. For each .md file that is not a reserved file (index.md, log.md):

  1. Parse the YAML frontmatter. If it has no frontmatter or no non-empty type, increment unparseable and skip the file.
  2. Compute the concept id = the file's path relative to the bundle root, with .md stripped (e.g. concepts/transformers.md → concepts/transformers). The target page is $VAULT/<concept-id>.md.
  3. Reverse-map frontmatter (the inverse of the canonical mapping table in wiki-export Step 3.5):
  • title ← title.
  • category ← the preserved category extension key if present; else lower-case the directory prefix of the concept id (concepts/… → concepts); else derive from type (Concept→concepts, Entity→entities, Skill→skills, Reference→references, Synthesis→synthesis, Project→projects, Journal→journal).
  • tags ← tags.
  • summary ← description.
  • updated ← timestamp (or now if absent).
  • created ← the preserved created extension key if present, else now.

Use this skill in a project

Open any RiverX project, search the Skills panel for ar9av/obsidian-wiki/wiki-import, and install it in one click.

Use this skill