Resolve targetKey by realpathing the nearest EXISTING ancestor and re-appending the missing suffix, so a not-yet-created file under a symlinked ancestor with missing intermediate dirs gets the same key before and after creation — keeping observed-state intact across a write→edit cycle. Make the socket-type probe test skip (not fail) when a sandbox forbids unix-domain sockets.
@deepseek-ai/dsh-fs-local
The local-filesystem implementation of the ctx.fs provider seam (@deepseek-ai/dsh-fs). Backs the six FileSystem primitives with the host filesystem; loading it as a plugin populates ctx.fs.
import { LocalFileSystem } from '@deepseek-ai/dsh-fs-local'
await ctx.plugin(LocalFileSystem, { cwd: process.cwd() })
// ctx.fs is now the local backend; load @deepseek-ai/dsh-file-context for policy
// and @deepseek-ai/dsh-tool-fs to expose read/write/edit to the model.
Behavior
resolve(path)— relative paths resolve fromconfig.cwd(defaultprocess.cwd()). ThetargetKeyis the file'srealpath, so two input paths reaching the same file through symlinks share one identity, and writes/edits land on the link target (preserving the link). A not-yet-existing path uses the realpathed parent directory plus basename when the parent exists; only an unresolvable parent falls back to the absolute path.displayPathis the absolute (un-resolved) path.stat— returnsFsInfo(version=mtimeMs:size,typeoffile/directory/other, bytesize) orundefinedwhen the target is absent.readText/streamText— UTF-8 only.readTextreads the whole file;streamTextstreams it in chunks (cross-chunk decoding) so a huge file never has to be held whole in memory. Both reject invalid UTF-8 and NUL-byte binary samples (FS_NOT_TEXT) and non-regular targets. The policy layer (ctx.fileContext) decides which to call by size and owns the line windowing.writeText— atomic: writes to a temp file opened exclusively (wx,0o600) inside a randomly-named private staging dir (0o700) next to the target, fsyncs, then renames over the target. An existing file's mode is preserved, while new files default to0o600. Honors theFsWriteExpectation:createIfAbsentcreates a missing target and rejects an existing one (FS_NOT_OBSERVED);replaceIfVersionreplaces only at the observed version (a missing target or mismatch isFS_STALE_VERSION).editText— atomic literal read-modify-write over the same primitive, serialized per target by a mutation lock. Verifies the expected version BEFORE literal matching (a stale edit reportsFS_STALE_VERSION, neverFS_EDIT_NOT_FOUND/FS_AMBIGUOUS_EDITagainst newer content), LF-normalizes for matching, restores the file's dominant CRLF/LF style, and rejects emptyoldString/ zero matches (FS_EDIT_NOT_FOUND) or ambiguous multi-matches withoutreplace_all(FS_AMBIGUOUS_EDIT).
cwd is not a sandbox
config.cwd is a resolution default, not a containment boundary — absolute paths and .. escape it. Enforce containment with a stricter ctx.fs backend or a permission plugin on the tools/execute waterfall. See the filesystem capability-seam RFC's Risks section.
The raw I/O lives in src/fsio.ts (Cordis-free, independently unit-tested); src/index.ts is the thin service wiring.