Skip to content

Importing from Obsidian

When to use

When a user asks to import an Obsidian vault — or any plain folder of Markdown + YAML frontmatter (Zettlr, generic exports). The Import tab hands the task straight to you: you own it end to end — run the import, then make the result feel native and resolve whatever couldn't be converted, asking the user when you need a decision. Read limestone-vault-conventions and working-with-collections first.

Run the import (one tool call)

Call limestone_import_notebook(path, collection_name) with the path to the vault folder (or a .zip of it). It runs the deterministic importer (below) — the whole bulk conversion at once — and returns a summary: collection, notes_imported, attachments_imported, attachments_skipped, warnings, and an unconverted list. Never import notes one at a time yourself. Then finalize (see below).

How the import works (what the tool does)

An Obsidian vault is a folder tree of .md files. Limestone's own note syntax is Obsidian's ([[wikilinks]], ![[embeds]], YAML frontmatter), so bodies mostly pass through; the importer's work is metadata and attachments:

Obsidian Limestone
the vault (the folder) one collection (named for the folder)
each .md file a record (row + Markdown note); duplicate titles get a numeric suffix so folders don't collide
frontmatter title (else the filename) the record title
frontmatter created/date, updated/modified Created / Updated date properties (ISO-8601)
frontmatter author, source/url, aliases Author / Source URL / Aliases text properties
frontmatter tags: + inline #tags real note tags
any other frontmatter key preserved back into the note's own frontmatter (a warning lists the keys)
![[image.png]] / ![](attachments/x.png) the file, stored beside the note, embedded inline as ![[filename]]
[[Note]] / [[Note#Heading]] links left as-is (same syntax); resolve to the imported notes

.obsidian/, .trash/, and other dotfolders are ignored. Remote image URLs (![](https://…)) are left as links.

Finalizing an import (your job)

After a run you get an ImportResult with counts, warnings, and an unconverted list. Make the collection feel native:

  1. Promote preserved frontmatter. The warnings list names frontmatter keys the importer kept in each note's YAML but didn't type (e.g. status, rating). If the user wants any as a real column, add the property and set values.
  2. Retype/confirm properties. Author imports as text; consider a user property if the vault has matching members. Confirm Created/Updated render as dates.
  3. Split or rename the collection if one vault clearly holds several distinct record types. Ask the user before large restructuring.
  4. Resolve unconverted items. Each names a note and a reason:
  5. attachment … Unsupported file type — a type the vault doesn't yet accept. Decide with the user: add the extension to VaultService.ARTIFACT_EXTENSIONS and re-run, convert it, or leave it out.
  6. embed … unresolved reference — an ![[…]] whose target file wasn't found in the vault (moved/renamed/external). Locate it with the user or drop the embed.

Evolving this skill (formats change)

If the importer reports many unconverted items of a new shape, work out the right mapping, apply it with the normal vault tools, and propose an update: extend this SKILL.md's mapping table, or — for a recurring structural change — flag that importers/markdown_folder.py needs a code change. Keep this file and the importer in sync (the importer's module docstring points back here).

Tips

  • Never re-do the bulk import by calling tools per note — that's the deterministic importer's job. Your value is judgment on the margins.
  • Re-running creates a second collection (import is collection-level idempotent only); prefer fixing in place.