Skip to main content

Obsidian Vault

@magistr/obsidian-vaultv2026.08.19.1· 23d agoMODELS
01README

Manage Obsidian vaults headlessly from a mounted directory, or via the official CLI (v1.12+) — notes, search, tags, links, daily notes, frontmatter, corpus digest

02Models1
@magistr/obsidian/vaultv2026.08.19.1extensions/models/obsidian_vault.ts

Global Arguments

ArgumentTypeDescription
vault?stringRegistered Obsidian vault name. Required for the CLI backend; also used to look up vaultRoot in Obsidian's vault registry when vaultRoot is not given.
vaultRoot?stringAbsolute path to the vault directory. Setting it enables the headless filesystem backend. Takes precedence over the registry lookup.
backendenumWhich backend to use: 'auto' picks fs when vaultRoot is set and cli otherwise; 'cli' always shells to the Obsidian binary (needs the desktop app running); 'fs' always reads the vault directory and refuses methods that need Obsidian's index.
blockDotObsidianbooleanRefuse to read or write inside .obsidian unless a method is called with allowDotObsidian=true.
defaultFileModenumberPermission mode applied to files the filesystem backend creates.
defaultDirectoryModenumberPermission mode applied to directories the filesystem backend creates.
fn list(folder?: string, ext?: string, recursive?: boolean, limit?: number, allowDotObsidian?: boolean)
List notes in the vault (filesystem backend when vaultRoot is set)
ArgumentTypeDescription
folder?stringFilter by folder path
ext?stringFilter by extension (e.g. 'md')
recursive?booleanDescend into subfolders (filesystem backend; default true)
limit?numberMaximum files to return
allowDotObsidian?booleanPermit traversal of .obsidian and other hidden directories
fn read(file: string, allowDotObsidian?: boolean)
Read a note's content
ArgumentTypeDescription
filestringPath to note (e.g. 'folder/note.md')
allowDotObsidian?booleanPermit reading inside .obsidian
fn fileInfo(file: string, allowDotObsidian?: boolean)
Show file metadata. Reports exists=false rather than failing when the note is absent.
ArgumentTypeDescription
filestringPath to note
allowDotObsidian?boolean
fn create(name: string, content?: string, template?: string, overwrite?: boolean, allowDotObsidian?: boolean)
Create or replace a note. Reports created, updated, or unchanged; an unchanged note is not rewritten.
ArgumentTypeDescription
namestringPath for the note (e.g. 'folder/note.md' or 'note')
content?stringNote content
template?stringTemplate name to use (CLI backend only)
overwrite?booleanOverwrite if file exists
allowDotObsidian?boolean
fn append(file: string, content: string, separator?: string, inline?: boolean, allowDotObsidian?: boolean)
Append content to the end of a note
ArgumentTypeDescription
filestringPath to note
contentstringContent to append
separator?stringText inserted between the existing content and the new content. Wins over inline; defaults to a newline.
inline?booleanShorthand for separator="" (append with no separator)
allowDotObsidian?boolean
fn prepend(file: string, content: string, separator?: string, inline?: boolean, allowDotObsidian?: boolean)
Prepend content after the frontmatter
ArgumentTypeDescription
filestringPath to note
contentstringContent to prepend
separator?stringText inserted between the new content and the existing content. Wins over inline; defaults to a newline.
inline?booleanShorthand for separator="" (prepend with no separator)
allowDotObsidian?boolean
fn delete(file: string, permanent?: boolean, dryRun?: boolean, allowDotObsidian?: boolean)
Delete a note. Moves it to the vault's .trash by default on both backends.
ArgumentTypeDescription
filestringPath to note
permanent?booleanPermanently delete instead of moving to trash
dryRun?booleanReport what would be removed without removing it
allowDotObsidian?boolean
fn move(file: string, to: string)
Move or rename a note, rewriting wikilinks (needs the Obsidian CLI)
ArgumentTypeDescription
filestringCurrent path
tostringDestination folder or path
fn search(query: string, folder?: string, path?: string, regex?: boolean, caseSensitive?: boolean, limit?: number, allowDotObsidian?: boolean)
Full-text search with matching line context
ArgumentTypeDescription
querystringSearch query
folder?stringLimit to folder
path?stringAlias for folder
regex?booleanTreat the query as a regular expression (filesystem backend only)
caseSensitive?booleanMatch case exactly (filesystem backend only)
limit?numberMax matches to return
allowDotObsidian?boolean
fn digest(folder?: string, datePrefixes?: array, nameContains?: array, signalKeywords?: array, maxFiles: number, maxBodyChars: number, allowDotObsidian?: boolean)
Scan the vault once and produce a queryable structural digest — headings, wikilinks, tags, refs, word counts, and signal-keyword rollups
ArgumentTypeDescription
folder?stringLimit the scan to a folder
datePrefixes?arrayOnly include files whose name starts with one of these prefixes
nameContains?arrayOnly include files whose name contains one of these substrings
signalKeywords?arrayKeywords to count across note bodies, each hit recorded with its line
maxFilesnumberStop after this many files and report truncated=true
maxBodyCharsnumberCharacters of body text to retain per note. Defaults to 0 — raising it copies note content into the swamp datastore.
allowDotObsidian?boolean
fn tags(counts?: boolean)
List all tags in the vault (needs the Obsidian CLI)
ArgumentTypeDescription
counts?booleanInclude occurrence counts
fn tag(name: string)
List files with a specific tag (needs the Obsidian CLI)
ArgumentTypeDescription
namestringTag name (e.g. '#swamp' or 'swamp')
fn links(file: string)
Show outgoing links from a note (needs the Obsidian CLI)
ArgumentTypeDescription
filestringPath to note
fn backlinks(file: string)
Show files linking to a note (needs the Obsidian CLI)
ArgumentTypeDescription
filestringPath to note
fn orphans()
List notes with no incoming links (needs the Obsidian CLI)
fn unresolved(verbose?: boolean)
List unresolved/broken links in the vault (needs the Obsidian CLI)
ArgumentTypeDescription
verbose?booleanInclude source files
fn daily()
Open or create today's daily note (needs the Obsidian CLI)
fn dailyRead()
Read today's daily note content (needs the Obsidian CLI)
fn dailyAppend(content: string, separator?: string, inline?: boolean)
Append content to today's daily note (needs the Obsidian CLI)
ArgumentTypeDescription
contentstringContent to append
separator?stringText inserted before the new content. Wins over inline; defaults to a newline.
inline?booleanShorthand for separator=""
fn dailyPrepend(content: string, separator?: string, inline?: boolean)
Prepend content to today's daily note (needs the Obsidian CLI)
ArgumentTypeDescription
contentstringContent to prepend
separator?stringText inserted after the new content. Wins over inline; defaults to a newline.
inline?booleanShorthand for separator=""
fn properties(file: string, allowDotObsidian?: boolean)
Read frontmatter properties of a note
ArgumentTypeDescription
filestringPath to note
allowDotObsidian?boolean
fn propertySet(file: string, name: string, value: string, type?: enum, allowDotObsidian?: boolean)
Set a single frontmatter property on a note
ArgumentTypeDescription
filestringPath to note
namestringProperty name
valuestringProperty value (use a JSON array for list types, e.g. \
type?enumProperty type hint
allowDotObsidian?boolean
fn setProperties(file: string, properties: record, allowDotObsidian?: boolean)
Merge several frontmatter properties into a note in one call
ArgumentTypeDescription
filestringPath to note
propertiesrecordProperty map to merge. Values may be strings, numbers, booleans, null, or arrays.
allowDotObsidian?boolean
fn propertyRemove(file: string, name: string, allowDotObsidian?: boolean)
Remove a frontmatter property from a note
ArgumentTypeDescription
filestringPath to note
namestringProperty name to remove
allowDotObsidian?boolean

Resources

note(infinite)— Single note content and metadata
fileInfo(infinite)— File metadata (existence, size, timestamps)
notes(infinite)— List of notes/files in vault
searchResults(infinite)— Search results with matching context
tags(infinite)— Tag listing
tagFiles(infinite)— Files matching a specific tag
links(infinite)— Links or backlinks for a note
unresolved(infinite)— Unresolved/broken links in vault
dailyNote(infinite)— Daily note content
properties(infinite)— Note frontmatter properties
operationResult(infinite)— Result of mutating operations
corpus(infinite)— Structural digest of the vault: per-note headings, wikilinks, tags, refs and word counts, plus signal-keyword rollups
03Previous Versions5
2026.08.02.1

2026.08.02.1

Test backfill to the STANDARD.md five-suite quality bar (ext-quality-bf-obsidian-vault, the LAST entry on quality-allowlist.txt — this backfill took the Phase D compliance program to 100%), followed by a real fix for all eight latent bugs the backfill's adversarial/coverage suites found and originally pinned: CRLF-frontmatter data loss, a ReDoS alternation guard gap, backslash path traversal, unbounded digest/search memory and per-file reads, digest silently ignoring an explicit CLI backend, impossible calendar dates, a trash-overwrite race, and hardcoded write-action reporting. obsidian_vault.ts and manifest.yaml both move version from 2026.07.27.1 to 2026.08.02.1.

  • Added extensions/models/obsidian_vault_methods_test.ts (methods — all 24 methods exercised at least once, mechanically verified by a final method-coverage assertion; the 11 CLI-only methods driven through a stubbed Deno.Command asserting argv plus response parsing; properties and propertyRemove get their first-ever .execute() coverage), obsidian_vault_adversarial_test.ts (adversarial — organized by the seven review-adversarial dimensions plus a dedicated filesystem-attack-surface section: path-confinement and symlink-refusal hold across all 13 fs methods, YAML/frontmatter-injection is prevented, the maxBodyChars=0 privacy default holds), obsidian_vault_coverage_test.ts (coverage — digest name-filter branches, a dotfile extension edge, propertyRemove's no-frontmatter/no-op paths, empty-query search, the path folder alias, selectBackend's no-headless-alternative message shape, propertyTypeHint(0)), obsidian_vault_property_test.ts (property-invariant-flow — npm:fast-check@4.8.0, gated by FC_NUM_RUNS, with domain-restricted arbitraries so merge-idempotence, readback fidelity, splitFrontmatter round-trip, a multi-step setProperties flow, and list-determinism all hold without flaking against the CRLF/YAML-escaping-needing domains; verified convergent at FC_NUM_RUNS=5000) — 0 tests before this change across these four files, 188 total across all five suites after (179 from the backfill, 9 net added by the real-fix pass below).
  • Added extensions/models/fixtures/PROVENANCE.md (synthetic-only banner covering all nine fixtures, six pre-existing plus three new) and three new adversarial fixtures: crlf-frontmatter.md (real CRLF byte pairs, written via printf so they survive Git unmodified — this repo has no .gitattributes line-ending rule), malformed-frontmatter.md (a tab character used for frontmatter indentation — invalid YAML), and unterminated-frontmatter.md (an opening --- fence that is never closed). No live vault was read to author any fixture — every value is an invented placeholder (see PROVENANCE.md for the full accounting).
  • deno.json: added fmt.exclude: ["extensions/models/fixtures/"] so deno fmt cannot silently corrupt the three byte-precise adversarial fixtures above (verified: without the exclude, deno fmt normalized the CRLF fixture's line endings and merged the unterminated fixture's two property lines into one paragraph). deno.lock gained the npm:fast-check@4.8.0 entry the property suite resolves.

Eight latent bugs found by the backfill's adversarial/coverage suites, filed in the LOCAL obsidian-vault-latent-bugs issue-lifecycle model (never the swamp.club Lab — this is our own extension), are now real-fixed:

  • #1 HIGH — CRLF frontmatter data loss. splitFrontmatter's opening-fence check only recognized ---\n; a CRLF-line-ended note's real frontmatter was silently invisible to readProperties, and setProperties/mergeProperties corrupted it by prepending a second frontmatter block. Fixed by also accepting ---\r\n — the existing closing-fence scan and body/raw slicing were already CRLF-tolerant. Added a non-vacuous end-to-end regression: write a CRLF note to a real temp vault, setProperties, read it back, and assert the original title survives alongside the new/changed properties, with exactly one frontmatter block (no duplication).
  • #2 MED — ReDoS alternation guard gap. The nested-quantifier guard only matched a quantifier inside a parenthesized group ((a+)+); an alternation-based group carrying its own quantifier ((a|a)+, (a|ab)*) passed through uncaught. Added a second guard, ALTERNATION_QUANTIFIER, rejecting any quantified alternation group. Accepted tradeoff: a non-catastrophic pattern like (cat|dog)+ is now also conservatively

Notes trimmed at a line boundary to fit the registry's 4900-byte per-version cap. Full section: https://github.com/umag/swamp-workspace/blob/d850d8e8372d4c0008c9245959a090b37095de7a/obsidian-vault/CHANGELOG.md

2026.07.27.1

Merge pull request #56 from umag/feat/obsidian-vault-fs-backend

obsidian-vault: headless filesystem backend, bulk frontmatter merge, and corpus digest

Modified 1 models

2026.07.16.2

Release 2026.07.16.2 — align model versions with manifests

Maintenance release across the @magistr extensions. For most packages this carries no functional change: the only edit is the model's version: field, brought back in line with its manifest version so the published model type version and the package version no longer drift.

Functional changes in this release are limited to:

  • anime-cron: normalizeTitle now strips a ": subtitle" suffix and a trailing parenthesized year before comparison, fixing dedup false-misses where the torrent title carries a subtitle or year that the AniList romaji does not.

  • arckit: first publish. Standalone ArcKit port — a 12-phase architecture governance state machine with 65 bundled templates, driven by a bundled skill.

Also tracks three extensions (kaiten, observability-agent, music-library) that previously existed only as untracked working-tree directories, recovered from stashes.

Added 1, removed 1 models

2026.05.25.1

Merge pull request #4 from umag/extensions/magistr-grade-a-workspace

extensions: stage 15 @magistr extensions as Grade A workspace dirs + wire CI

2026.03.28.2
04Stats
A
100 / 100
Downloads
29
Archive size
103.7 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License declared1/1earned
  • Verified public repository2/2earned
05Platforms
06Labels