description: "The host-filesystem backend for ctx.fs for deployments and maintainers choosing or debugging local file access."
English | 中文
Use dsh-fs-local to read, list, atomically write, and edit files on the host filesystem. Relative paths resolve from a configurable base directory, while absolute paths and parent traversal remain unrestricted. Paths and symlinks that reach the same file share one identity. Writes preserve file permissions, and optional version guards reject stale overwrites. Choose this package for direct host access; use fs-sandbox for confined mutations.
Mount this backend when a composition needs ctx.fs backed by the real host filesystem and accepts a process-local implementation. The common path is explicit: load the backend, give it a base directory, and the model-facing tools (dsh-tool-fs) or your own plugins can read, write, and edit files.
Choose fs-local for ordinary host-file access in a single process. Choose fs-sandbox when a session's writes and edits must be confined to its workspace and temp roots — it extends this backend and adds only the mode fence. config.cwd is a resolution default, not a containment boundary: absolute paths and .. escape it.
Load the backend with a base directory; relative paths resolve against it, and absolute paths ignore it. A relative base is anchored to the provider process working directory, and display paths remain absolute. On POSIX, resolution follows filesystem semantics before lexical normalization: symlink/.. reaches the parent of the link target, including when the final file does not exist yet. Directory listings preserve the same physical traversal in displayed child paths. Windows retains native drive-relative normalization.
- name: '@deepseek-ai/dsh-fs-local'
config:
cwd: /absolute/path/to/workspace
| Field | Default | Meaning |
|---|---|---|
cwd |
process.cwd() |
Base directory for relative paths |
diffBasisMaxBytes |
10 MiB |
UTF-8 byte limit per overwrite-diff side; larger overwrites return before: null |
The generated configuration catalog is the exhaustive source for every accepted field and its JSDoc.
Read any regular UTF-8 text file whole or as a stream, read raw bytes up to a cap you choose or in a byte window, and list one directory level in stable name order. Create or replace a file atomically, and apply a literal text edit atomically; both mutations serialize per file, so concurrent writers never interleave. The version guard is optional: omit it for unconditional create-or-overwrite, or supply it to fail when the file changed since you last observed it.
Failures are typed FsErrors with stable codes — FS_NOT_FOUND, FS_NOT_TEXT (binary content), FS_STALE_VERSION (changed since observation), FS_EDIT_NOT_FOUND or FS_AMBIGUOUS_EDIT (no unique literal match), and others — so callers branch on the code, never on message text. A missing target on an edit reports FS_STALE_VERSION whether or not the version guard is supplied.
Read these pages when the package-level contract is not enough. They move from the contract to the adjacent backends, tools, and policies.
ctx.fs contract this backend implements.ctx.fs.fs/* events.Indirectly, through dsh-tool-fs, which renders this provider's line-windowed UTF-8 content, mutation acknowledgements, and exact provider messages in capped retained results while versions, atomic-write mechanics, and directory metadata remain internal.
No direct invalidation; the named consumer owns any request-prefix changes.
These limits define when the local backend is a poor fit or needs special operational care. They are current package constraints, not a general filesystem comparison or a task backlog.
config.cwd is not a sandbox — it is a resolution default, not containment: absolute paths and .. escape it. Enforce containment with a stricter ctx.fs backend or a permission plugin on the tools/execute waterfall.editText holds the whole file (plus the edited copy) in memory — streaming exists only on the read path.writeText may retain up to just below config.diffBasisMaxBytes of prior text in addition to the caller-owned replacement; the bound does not cap the returned after value or the whole-file presentation fallback.createIfAbsent; the backend preserves the missing target and reports FS_IO_ERROR.Runtime invariant: No companion is published. This package exposes no independent event sequence or mutable data relation beyond contracts enforced at its owning seam.