Shared engine for Obsidian VFS. Provides obs:// URI resolution, file I/O, Obsidian CLI integration, LRU caching, and content processing used by all consumer packages.
- URI resolution —
obs://scheme handling,@obs:context mentions,/obs:skill mentions,[[wikilink]]resolution. - File I/O — Direct reads via
node:fs(bypassing the CLI for performance), directory enumeration, file watching. - Obsidian CLI wrapper — Async queue-serialized calls to the
obsidianbinary for search, backlinks, vault discovery. JSON and plain-text response parsing. - Content processing — Section slicing by
#heading,[[wikilink]]scrubbing toobs://URIs,![[embed]]transclusion, Markdown link parsing. - Frontmatter — Extraction, curation, and formatting of YAML frontmatter. Model field mapping to Claude model identifiers via
mapModelToClaude(). - Mount tree — Pure visibility logic for partial
autoMountpaths. Used by VSCode to computefiles.excludesub-directory exclusions that match tree view visibility. - Caching — Generic
LRUCache<K, V>with TTL expiration. - Security —
path.resolve+ vault-root prefix check on all I/O. Symlink rejection outside vault.allowed/blockedenforcement on general vault content;agents/skillsimplicitly allowed. - Configuration — Vault config from
.obsidian/obsidian-vfs.json(agents,skills,allowed,blocked).
The package exposes two entry points:
| Entry | Path | Purpose |
|---|---|---|
. |
dist/index.js |
All production exports |
./testing |
dist/test-helpers.js |
Test utilities and mocks |
The ./testing entry point provides test doubles for consumer packages:
| Utility | Description |
|---|---|
mockCLI(overrides?) |
Fully-stubbed ObsidianCLI mock with optional per-method overrides |
mockFsFunction(fn) |
Type-safe cast wrapper for mocked node:fs/promises functions |
makeLocalIndexTrackerWith(methodName, result, extraMethods?, contextOverrides?) |
Build a mock LocalIndexTracker whose single method resolves to a given VFSResult |
makeDiscoveredResource(overrides?) |
Build a DiscoveredResource with sensible defaults |
| Category | Symbols |
|---|---|
| Resolution | resolveMention, resolveSkillMention, resolveWikilink, normalizeMention, parseSection |
| File I/O | readVirtualFile, listMarkdownFiles, listFolders, readDirectory |
| CLI | ObsidianCLI, resolveExecConfig, resolveCliPath |
| Content | sliceContent, scrubWikilinks, processContent, resolveEmbeds, maskCodeRegions |
| Frontmatter | extractFrontmatter, extractCuratedFrontmatter, remapModelLine, mapModelToClaude |
| Types | VFSResult, VFSError, VFSConfig, ErrorCode, MentionKind |
| Mount tree | buildMountTree, MountNode |
| Utilities | LRUCache, LocalIndexTracker, AsyncQueue |
| Constants | URI_SCHEME, URI_PREFIX, MENTION_PREFIX, SKILL_PREFIX |
All fallible operations return VFSResult<T>, a discriminated union:
type VFSResult<T> = { ok: true; value: T } | { ok: false; error: VFSError };No nulls, no thrown exceptions for expected failures.
The Obsidian CLI returns different formats per command:
search,backlinks→ JSONvault,files,folders,read→ plain text- Exit code is always
0; detect errors viaError:prefix in stdout.
When Obsidian is not running, the core falls back to node:fs for reads and enumeration. Search and wikilink resolution are unavailable in this mode.