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.
4.1 KiB
| title | tags | ||
|---|---|---|---|
| Filesystem operations |
|
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.