@obsidian-vfs/core
v0.3.1
Published
Core library for Obsidian VFS — vault resolution, content processing, path security
Readme
@obsidian-vfs/core
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.
Responsibilities
- 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).
Exports
The package exposes two entry points:
| Entry | Path | Purpose |
|-------|------|---------|
| . | dist/index.js | All production exports |
| ./testing | dist/test-helpers.js | Test utilities and mocks |
Testing Utilities
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 |
Key Exports
| 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 |
Result Types
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.
CLI Parsing Convention
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.
Degraded Mode
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.
