sotashimozono_obsidian-remo.../docs/en/api/filesystem.md
Souta 8d21b94bc8 fix(docs): third-pass — mostly self-inflicted, plus a fabricated safety net
Critical:
- conflicts.md: removed the entirely fictional "save a copy backstop"
  section (.bak files at <vault>/.obsidian-remote/conflicts/ + a
  "Clear conflict backups older than 30 days" action). None of this
  exists in ConflictResolver.ts; users could pick "Keep remote"
  expecting recoverable backups when there are none. Replaced with
  an explicit warning that there is no backup.
- user-guide/host-keys.md: corrected the mismatch dialog mockup I
  broke in pass 2. Actual mismatch modal has 2 buttons (Abort /
  Trust new key & reconnect), not 3. Title is "Remote host key
  changed", not "Host key MISMATCH for ...".
- security/host-keys.md: removed the fabricated "Hold Alt + click
  Trust" trust-once mechanism — no Alt-modifier exists; trust-once
  is its own button on the TOFU dialog only. Also corrected the
  mismatch button name from "Cancel" to "Abort" and removed the
  invented "two-step confirm protects against single-click attacks"
  rationale (no two-step exists).

Important:
- api/filesystem.md: fs.walk recursive default is false (Go zero),
  not true — clients must opt in.
- operations/logs.md, configuration/advanced.md, first-connect.md:
  log rotation keeps 4 files (console.log + .1 + .2 + .3), not 3.
  MAX_GENERATIONS=3 is the BACKUP count, not the total.

Advisory:
- api/errors.md: the example envelope used to show `data: { ... }`
  immediately before the prose said "data is omitted entirely" —
  removed `data` from the example, added a forward reference to the
  Error data field section.
2026-05-10 14:31:54 +09:00

4.1 KiB

title tags
Filesystem operations
api
reference

Filesystem operations

All fs.* methods are client→server, JSON-RPC over the daemon socket. All paths are vault-relative, forward-slash, no .. (see en/api/overview).

Read

fs.stat

Metadata for one path. Returns null if the path does not exist (NOT an error).

params: { path: string }
result: Stat | null

interface Stat {
  type: 'file' | 'folder';
  mtime: number;             // unix milliseconds
  size: number;              // bytes (0 for folders)
  mode: number;              // POSIX mode bits, informational
}

fs.exists

Fast existence check.

params: { path: string }
result: { exists: boolean }

fs.list

List directory contents (non-recursive). Fails if path is not a directory.

params: { path: string }
result: { entries: Entry[] }

interface Entry {
  name: string;              // basename only
  type: 'file' | 'folder' | 'symlink';
  mtime: number;
  size: number;
}

fs.walk

Recursive tree walk with optional cap.

params: {
  path: string;
  recursive?: boolean;       // default false; pass true to descend
  maxEntries?: number;       // budget; truncates beyond
}
result: {
  entries: WalkEntry[];      // path is vault-relative
  truncated: boolean;
}

interface WalkEntry {
  path: string;              // vault-relative
  type: 'file' | 'folder' | 'symlink';
  mtime: number;
  size: number;
}

fs.readText

UTF-8 text read.

params: { path: string; encoding?: 'utf8' }
result: { content: string; mtime: number; size: number; encoding: 'utf8' }

fs.readBinary

Full binary read, base64-encoded.

params: { path: string }
result: { contentBase64: string; mtime: number; size: number }

fs.readBinaryRange

Partial binary read. Clamps silently past EOF. expectedMtime precondition causes the request to fail with PreconditionFailed if the file changed mid-read.

params: {
  path: string;
  offset: number;
  length: number;
  expectedMtime?: number;
}
result: { contentBase64: string; mtime: number; size: number }

fs.thumbnail

Server-side image resize. JPEG q=80 or PNG (preserves alpha).

params: { path: string; maxDim: number }
result: {
  contentBase64: string;
  mtime: number;
  sourceSize: number;
  format: 'jpeg' | 'png';
  width: number;
  height: number;
}

Write

fs.write / fs.writeBinary

Atomic write (tmp file + rename). Fails with PreconditionFailed (-32020) if expectedMtime does not match current.

params: {
  path: string;
  content: string;          // (or contentBase64 for binary)
  expectedMtime?: number;
}
result: { mtime: number }

expectedMtime is the conflict-detection mechanism — see en/user-guide/conflicts.

fs.append / fs.appendBinary

Append-only write.

params: { path: string; content: string }   // or contentBase64
result: { mtime: number }

fs.mkdir

Create directory. recursive: true creates parent dirs (mkdir -p).

params: { path: string; recursive?: boolean }
result: {}

fs.remove / fs.rmdir

Delete. fs.remove for files; fs.rmdir for directories. rmdir with recursive: true deletes contents.

params: { path: string; recursive?: boolean }   // recursive only on rmdir
result: {}

fs.rename

Atomic rename. Creates destination parent dirs if needed.

params: { oldPath: string; newPath: string }
result: { mtime: number }

fs.copy

Copy file contents (no server-side reflink yet; reads + writes).

params: { srcPath: string; destPath: string }
result: { mtime: number }

fs.trashLocal

Move path under <vaultRoot>/.trash/…. Creates intermediate dirs.

params: { path: string }
result: {}

A future fs.trashSystem is on the roadmap to route to the OS trash via gio trash / osascript; until then, only the in-vault .trash/ form exists.

Next: en/api/watch.