Expand description
Filesystem state sync (docs/fs-watch.md): opcodes, record codecs, and the client-side mirror reducer. Filesystem state sync wire protocol (docs/fs-watch.md).
The server maintains a canonical replica of a watched tree and streams
per-client state diffs (FS_UPDATE). Clients apply records to a map and
acknowledge. Snapshots and recovery are RESET … SYNC staged series;
loss and overflow are not wire concepts.
All integers little-endian, tightly packed, as everywhere in the protocol.
Structs§
- FsMirror
- The complete client obligation: apply updates, read
live. - FsNode
- One node in a mirrored tree.
- FsOp
- A metadata op (
C2S_FS_OP):opselects mkdir/remove/rename;ais the primary path,bthe rename destination.base/modeare used by only some ops (likeLSP_QUERY’sline/col). - FsRecord
Iter - Iterate records in an uncompressed
FS_UPDATEpayload. Unknown kinds are skipped viarecord_len; a malformed record ends iteration (the update is applied up to that point and the rest dropped — forward-compatible with future record extensions). - FsWrite
- A content write (
C2S_FS_WRITE).baseis the CAS precondition: the current on-disk content hash to match (non-zero), zero for create-exclusive, ignored underFS_WRITE_NO_CAS.
Enums§
- FsContent
- FsGrep
Record - One record of an
FS_GREPresponse. - FsRecord
- One decoded record from an
FS_UPDATEpayload.
Constants§
- C2S_
FS_ ACK - Cumulative acknowledgement: [0x42][sync_id:2][update_id:4]
- C2S_
FS_ FETCH - Fetch full content of one file: [0x43][nonce:2][sync_id:2][path_len:2][path:N]
- C2S_
FS_ GREP - Content search under a root (no sync), docs/design/fs-grep.md:
[0x48][nonce:2][flags:1][max_matches:2][max_per_file:2][root_len:2][root:N][query_len:2][query:N].
flagsisFS_GREP_CASE_SENSITIVE|FS_GREP_REGEX; zero maxima mean the server defaults. UnlikeFS_INDEXthe walk does not skip ignored files — it ranks them last. - C2S_
FS_ INDEX - Fetch the candidate file list under a root (no sync), for client-side
fuzzy search (docs/design/fs-search.md): [0x47][nonce:2][flags:1][root_len:2][root:N].
flagsis reserved; nonzero answersINVALID. - C2S_
FS_ OP - Metadata op (mkdir/remove/rename): [0x45][nonce:2][sync_id:2][op:1][flags:1][base:16][mode:4][a_len:2][a:N][b_len:2][b:N]
- C2S_
FS_ SEARCH - Fuzzy file search under a root (no sync): [0x46][nonce:2][limit:2][root_len:2][root:N][query_len:2][query:N].
Returns paths (root-relative) whose basename subsequence-matches
query. - C2S_
FS_ STOP - Stop a sync: [0x41][sync_id:2]
- C2S_
FS_ SYNC - Start (or replace) a sync: [0x40][nonce:2][flags:2][latency_ms:2][inline_max:4][path_len:2][path:N]
then, when
FS_SYNC_EXCLUDEis set, [exclude_len:2][exclude:M]; then, whenFS_SYNC_FROM_PTYis set, [src_pty_id:2]. - C2S_
FS_ WRITE - Write file content (CAS): [0x44][nonce:2][sync_id:2][flags:1][base:16][mode:4][content_kind:1][path_len:2][path:N][content:LZ4]
- FEATURE_
FS S2C_HELLOfeature bit: server supports theFS_*message family, reads and writes alike (docs/design/fs-watch.md, docs/design/fs-write.md). A read-only deployment (BLIT_FS_WRITE=0) still advertises this bit and answersFS_WRITE/FS_OPwithFS_DONE_PERMISSION.- FS_
CLOSED_ BACKEND_ FAILED - FS_
CLOSED_ CLIENT_ REQUEST - FS_
CLOSED_ PERMISSION_ LOST - FS_
CLOSED_ RESOURCE_ LIMIT - FS_
CLOSED_ ROOT_ GONE - FS_
CONTENT_ DELTA - FS_
CONTENT_ FULL - FS_
CONTENT_ NONE - FS_
DONE_ BUDGET - FS_
DONE_ CONFLICT - A precondition failed (CAS mismatch, create-exclusive on an existing
path, conditional remove on a changed file). On
CONFLICT,FS_DONE.hashcarries the current on-disk hash so the client rebases without a round trip. Added in lsp’s10 WARMINGextension style. - FS_
DONE_ INVALID - FS_
DONE_ NOT_ FOUND - FS_
DONE_ OK - FS_
DONE_ OTHER - FS_
DONE_ PERMISSION - FS_
DONE_ TOO_ LARGE - FS_
DONE_ WRONG_ TYPE - FS_
ENTRY_ DIR - FS_
ENTRY_ FILE - FS_
ENTRY_ FILTERED - Set on a directory whose enumeration skipped at least one child the sync’s exclusion rules cover (docs/design/fs-watch.md “Ignoring”). Excluded paths are absent rather than marked, so without this a client cannot tell an empty directory from a filtered one — a file browser needs it to say “some items hidden” instead of showing a folder that looks wrong.
- FS_
ENTRY_ LINK_ DIR - Set on an
FS_ENTRY_SYMLINKwhose target is a directory, which the sync enumerates like any other. Clients need it to know the entry is expandable: the type alone cannot distinguish a link to a directory from one to a file, and a non-recursive sync has no children listed yet to infer it from. - FS_
ENTRY_ NO_ CONTENT - Content omitted: over
inline_maxor the sync did not request content. - FS_
ENTRY_ OTHER - FS_
ENTRY_ SYMLINK - FS_
ENTRY_ TYPE_ MASK - FS_
ENTRY_ UNREADABLE - Entry exists but its content could not be read.
- FS_
ENTRY_ UNSTABLE - File changed repeatedly while being read; content omitted, another upsert follows once it settles.
- FS_
FILE_ NOT_ FOUND - FS_
FILE_ OK - FS_
FILE_ OTHER - FS_
FILE_ UNREADABLE - FS_
GREP_ CASE_ SENSITIVE - Match case exactly. Unset (the default) is case-insensitive.
- FS_
GREP_ FILE_ IGNORED - The file is gitignored. It still gets searched — ignore rules rank rather than filter here — but sorts after every non-ignored file.
- FS_
GREP_ FLAGS_ KNOWN - Bits a request may set; anything else answers
INVALID. - FS_
GREP_ MAX_ LINE - Longest matched line returned, in bytes; longer lines are truncated on a UTF-8 boundary so a minified bundle costs one line of wire, not one line of megabyte.
- FS_
GREP_ NO_ IGNORE - Search gitignored files too, ranked after every tracked one. Unset (the
default) applies ignore rules and skips them — on a real repo that is
the difference between milliseconds and seconds, because the ignored
pass is what has to descend into
target/. - FS_
GREP_ RECORD_ FILE - FS_
GREP_ RECORD_ MATCH - FS_
GREP_ REGEX queryis a regex. Unset (the default) treats it as a literal string.- FS_
GREP_ TRUNCATED - A budget clipped the search: matches exist that are not in this response. Exact — set only when something was actually dropped.
- FS_
GREP_ WORD - Match only whole words: the pattern is wrapped in
\b(?:...)\bafter any literal escaping, so it composes with either mode. Same semantics asblit terminal grep --word-regexp. - FS_
INDEX_ MAX_ COUNT - Protocol cap on
S2C_FS_INDEX.count. The server’s entry budget clamps to this, and parsers treat a larger count as malformed — without it, a hostile count of tiny records could force a giant preallocation from a small frame (the decompression guard bounds bytes, not record counts). - FS_
INDEX_ TRUNCATED - The walk hit its entry or byte budget; the list is a prefix, not the
whole tree. Clients should keep server-side
FS_SEARCHfor this root. - FS_
MAX_ DECOMPRESSED - Cap on any single LZ4-decompressed fs payload — the protocol-wide
crate::MAX_DECOMPRESSEDguard (docs/protocol.md). Checked against the prepended size before allocating, so a hostile or corrupt length cannot force a giant allocation (the terminal path has the same guard). Large trees arrive as many bounded updates, never one huge one; content records are bounded by the sync’sinline_max(16 MiB default). - FS_
OP_ HARDLINK - Create a hard link at
bto the regular file ata(both wire paths under the root).baseCASes on the current entry atb. - FS_
OP_ MKDIR - FS_
OP_ MKPARENTS - FS_
OP_ NO_ CAS - FS_
OP_ REMOVE - FS_
OP_ RENAME - FS_
OP_ SYMLINK - Create or retarget a symlink at
bwhose target is the verbatim stringa(not a wire path; not confined to the root).baseCASes on the current entry atb— a symlink’s content hash is BLAKE3-128 of its target bytes (docs/design/fs-write.md “Links”). - FS_
RECORD_ DELETE - FS_
RECORD_ MOVE - FS_
RECORD_ UPSERT - FS_
STATUS_ NOT_ FOUND - FS_
STATUS_ OK - FS_
STATUS_ OTHER - FS_
STATUS_ PERMISSION_ DENIED - FS_
STATUS_ RESOURCE_ LIMIT - FS_
SYNC_ CONTENT - FS_
SYNC_ CROSS_ FILESYSTEM - FS_
SYNC_ DOTIGNORE - Honor
.ignorein and above the root — ripgrep’s convention, which a project uses to hide things from tooling without telling git to stop tracking them. Separate fromGITIGNOREbecause the two answer different questions, and.ignorebrings none of git’s repository-wide sources with it.FS_INDEXandFS_GREPapply both together; a sync picks. - FS_
SYNC_ EXCLUDE - A trailing
[exclude_len:2][exclude:M]carries client patterns — gitignore syntax, one per line, anchored at the sync root and applied above every other rule, so!keepre-includes. The flag is what makes the field parseable, and what makes a server too old to filter refuse the sync outright instead of silently mirroring the whole tree. - FS_
SYNC_ EXCLUDE_ GIT - Omit every entry whose final component is exactly
.git— directory or gitfile — from enumeration, hashing, hints, and records. A pure name filter: no git data is read (docs/design/fs-watch.md “Ignoring”). - FS_
SYNC_ EXCLUSION_ FLAGS - Every exclusion flag, which is also the set
SINGLErejects. - FS_
SYNC_ FLAGS_ KNOWN - Bits a
C2S_FS_SYNCmay set; anything else answers with the unknown-flags refusal. - FS_
SYNC_ FROM_ PTY - Resolve the sync’s base directory from a pty’s live cwd: a trailing
[src_pty_id:2]names a pty and the server joinspathonto its cwd (docs/ide.md Decision 3). It comes last, after anyEXCLUDEfield. - FS_
SYNC_ GITIGNORE - Honor
.gitignorein and above the root, plus the governing repository’s$GIT_DIR/info/exclude, the user’score.excludesFile, and itscore.ignorecase. Off by default, so a sync only narrows when asked. - FS_
SYNC_ HEADER - Fixed part of
C2S_FS_SYNC, up to and includingpath_len. - FS_
SYNC_ ID_ INVALID sync_idreported by a failedFS_SYNCED.- FS_
SYNC_ RECURSIVE - FS_
SYNC_ SINGLE - The sync root is a single FILE, not a directory: the mirror holds
exactly one entry — the root itself — keyed by the empty relative path
“” (the same key a directory sync gives its root). Combining with
RECURSIVEis invalid, and a directory root answers the invalid-path error (docs/design/fs-watch.md “Single-file sync”). Content,inline_max,FS_FETCH, and the write family behave as for any other sync, addressing path “”. - FS_
UPDATE_ RESET - Begin a staged snapshot: apply this and subsequent records to an empty staging map instead of the live map.
- FS_
UPDATE_ SYNC - Atomically replace the live map with the staging map (no-op without one).
- FS_
WRITE_ CONTENT_ DELTA - FS_
WRITE_ CONTENT_ FULL - FS_
WRITE_ DURABLE - fsync the file and its parent (F_FULLFSYNC on macOS) before returning.
- FS_
WRITE_ FOLLOW_ SYMLINK - Write through a final-component symlink whose resolved target stays under the root; default refuses one.
- FS_
WRITE_ MKPARENTS - Create missing parent directories.
- FS_
WRITE_ NO_ CAS - Ignore
base; unconditional overwrite/create (“Save As, replace”). - S2C_
FS_ CLOSED - Sync terminated: [0x43][sync_id:2][reason:1]
- S2C_
FS_ DONE - Write/op result: [0x44][nonce:2][status:1][hash:16][mtime_ns:8]
- S2C_
FS_ FILE - Fetch response: [0x42][nonce:2][status:1][data:LZ4]
- S2C_
FS_ GREP - Grep result: [0x47][nonce:2][status:1][flags:1][detail_len:2][detail:N][records:LZ4]
where the decompressed payload is a
[record_len:4][kind:1][..]stream ofFILE/MATCHrecords (docs/design/fs-grep.md). Status is the unified table (FS_DONE_*);detailcarries a regex compile error onINVALID. - S2C_
FS_ INDEX - Index result: [0x46][nonce:2][status:1][flags:1][count:4][paths:LZ4]
where the decompressed payload is repeated{ [path_len:2][path:N] },
root-relative, sorted. Status is the unified table (
FS_DONE_*). - S2C_
FS_ SEARCH - Search result: [0x45][nonce:2][status:1][count:2] repeated{ [path_len:2][path:N] }
- S2C_
FS_ SYNCED - Sync accepted or rejected: [0x40][nonce:2][sync_id:2][status:1][detail_len:2][detail:N] On success detail is the canonical root (UTF-8); on failure a diagnostic.
- S2C_
FS_ UPDATE - State diff: [0x41][sync_id:2][update_id:4][flags:1][records:LZ4]
Functions§
- append_
fs_ grep_ record - Append one record to an uncompressed
FS_GREPrecords buffer. - append_
fs_ record - Append one record to an uncompressed
FS_UPDATErecords buffer. - apply_
fs_ delta - Apply a content delta (LEB128 COPY/INSERT instruction stream) to a base.
- fs_
done_ status_ text - Human-readable name for an
FS_DONEstatus code. - fs_
grep_ records - Decode an uncompressed
FS_GREPrecords buffer. Unknown kinds are skipped viarecord_len; a record whose body overruns ends the stream, matching the TypeScript mirror. - fs_
records - fs_
sync_ exclude - Client exclude patterns from a
C2S_FS_SYNC—""whenEXCLUDEis unset.Nonemeans malformed: a truncated field or non-UTF-8 patterns. - fs_
sync_ flags - The
flagsfield of aC2S_FS_SYNC, orNoneif it is truncated. - fs_
sync_ flags_ valid C2S_FS_SYNCflag-combination validity:SINGLEsyncs exactly one file, soRECURSIVEcontradicts it and the pair is rejected at validation (docs/design/fs-watch.md “Single-file sync”). The exclusion flags apply to enumeration, whichSINGLEdoes none of, so they are rejected with it too rather than silently doing nothing.- fs_
sync_ rebase - Rebase a
FROM_PTYC2S_FS_SYNConto a resolvedcwd: joincwd/pathand clearFROM_PTY, producing a plain path-based sync the handler consumes unchanged.cwdNone(source pty gone) keepspathverbatim. Any exclude field rides along — the filter is the client’s, not the pty’s, and dropping it here would silently widen the sync. - fs_
sync_ src_ pty - Extract the trailing
src_pty_idfrom aFROM_PTYC2S_FS_SYNC;Nonewhen the flag is unset or the field is missing. - fs_
update_ records - Decompress an
FS_UPDATE’s records buffer (for consumers that want the records themselves, e.g. event display), with the standard guard. - msg_
fs_ ack - msg_
fs_ closed - msg_
fs_ done - Build an
S2C_FS_DONE. On successhash/mtime_nsare the post-op stat; onCONFLICT,hashis the current on-disk hash. - msg_
fs_ fetch - msg_
fs_ file - msg_
fs_ grep - Build a
C2S_FS_GREP. - msg_
fs_ grep_ result - Build an
S2C_FS_GREPfrom an uncompressed records buffer. - msg_
fs_ index - Build a
C2S_FS_INDEX. - msg_
fs_ index_ result - Build an
S2C_FS_INDEXresult.pathsshould be root-relative and sorted — sorted lists share prefixes, which is what makes the LZ4 payload small. - msg_
fs_ op - msg_
fs_ search - Build a
C2S_FS_SEARCH. - msg_
fs_ search_ result - Build an
S2C_FS_SEARCHresult. - msg_
fs_ stop - msg_
fs_ sync - msg_
fs_ sync_ excluding - Build a
C2S_FS_SYNCcarrying client exclude patterns: gitignore syntax, one per line, anchored at the sync root (docs/design/fs-watch.md “Ignoring”). SetsFS_SYNC_EXCLUDE; an emptyexcludebuilds the plain form instead, so a caller need not special-case “no patterns”. - msg_
fs_ sync_ from_ pty - Build a
C2S_FS_SYNCwhose base directory the server resolves from a pty’s live cwd: setsFS_SYNC_FROM_PTYand appends[src_pty_id:2]last (docs/ide.md Decision 3).pathis joined onto the resolved cwd server-side (empty = the cwd itself). - msg_
fs_ sync_ full - Every
C2S_FS_SYNCvariant, in field order. The optional trailers are self-describing through their flags —EXCLUDEfirst,FROM_PTYlast — which is what lets a parser skip one to reach the other. - msg_
fs_ synced - msg_
fs_ update - Build an
FS_UPDATEfrom an uncompressed records buffer. - msg_
fs_ write - parse_
fs_ done - Parse an
S2C_FS_DONEinto(nonce, status, hash, mtime_ns). - parse_
fs_ file - Parse an
S2C_FS_FILEmessage (starting at the opcode byte) into(nonce, status, data). Applies the same decompression guard asFsMirror::apply_update;None= malformed or over-sized. - parse_
fs_ grep - Parse a
C2S_FS_GREP→(nonce, flags, max_matches, max_per_file, root, query). - parse_
fs_ grep_ result - Parse an
S2C_FS_GREP→(nonce, status, flags, detail, records)with the records decompressed under the standard guard. - parse_
fs_ index - Parse a
C2S_FS_INDEX→(nonce, flags, root). - parse_
fs_ index_ result - Parse an
S2C_FS_INDEX→(nonce, status, flags, paths). Applies the standard decompression guard;None= malformed, over-sized, or a payload that disagrees withcount. - parse_
fs_ op - Parse a
C2S_FS_OP.None= malformed or a non-UTF-8 path. - parse_
fs_ search - Parse a
C2S_FS_SEARCH→(nonce, limit, root, query). - parse_
fs_ search_ result - Parse an
S2C_FS_SEARCH→(nonce, status, paths). - parse_
fs_ write - Parse a
C2S_FS_WRITE.None= malformed, non-UTF-8 path, or content whose declared decompressed size exceeds the protocol cap.