# ctx.fs `FileSystem` (abstract seam) — provided by `@deepseek-ai/dsh-fs`. Abstract filesystem provider. Targets must preserve identity across aliases; reads expose regular UTF-8 text or typed errors, listings are stable and content-free, and mutations are atomic. Optional guards add stale protection without changing the unguarded provider contract. [Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L80) ### ctx.fs.resolve(path, opts?) ```ts website-api abstract resolve(path: string, opts?: { cwd?: string; signal?: AbortSignal }): Promise ``` Resolve a model/plugin-supplied path into a stable FsTarget. May perform I/O (a remote/sandboxed backend may need a round-trip to map a path to a stable identity), hence async even though the local backend only normalizes + realpaths. - `path` — the path to resolve; relative paths resolve against `opts.cwd`. - `opts` — optional cwd override and cancellation signal. **Returns** the stable target; the same file yields the same `targetKey`. [Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L94) ### ctx.fs.stat(target, signal?) ```ts website-api abstract stat(target: FsTarget, signal?: AbortSignal): Promise ``` Return target metadata, or `undefined` when the target does not exist. - `target` — the resolved target to stat. - `signal` — aborts the metadata round-trip. **Returns** metadata only, never content; undefined for an absent target. [Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L102) ### ctx.fs.lstat(path, opts?, signal?) ```ts website-api abstract lstat(path: string, opts?: { cwd?: string }, signal?: AbortSignal): Promise ``` Return path metadata without following the final path component when it is a symbolic link. This is intentionally path-shaped, not target-shaped: resolve follows symlinks to produce the stable identity used by normal reads/writes, while `lstat` lets a consumer reject the path itself before that follow happens. `opts.cwd` follows resolve's cwd rules. `undefined` means the path is absent. - `path` — the path to inspect; relative paths resolve against `opts.cwd`. - `opts` — `cwd` overrides the backend's default base for relative paths. - `signal` — aborts the metadata round-trip. **Returns** metadata only, never content; undefined for an absent path. [Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L118) ### ctx.fs.readText(target, signal?) ```ts website-api abstract readText(target: FsTarget, signal?: AbortSignal): Promise ``` Read the whole regular text file as a single decoded string. - `target` — the resolved target to read. - `signal` — aborts the read. **Returns** the full decoded UTF-8 content. [Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L126) ### ctx.fs.streamText(target, signal?) ```ts website-api abstract streamText(target: FsTarget, signal?: AbortSignal): Promise> ``` Stream the whole regular text file as decoded text chunks (same text semantics as readText, for large files). The backend owns cross-chunk UTF-8 decoding and binary rejection so the policy layer never touches raw bytes. - `target` — the resolved target to read. - `signal` — aborts the stream, including between chunks. **Returns** the chunk iterable, decoded and validated like `readText`. [Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L137) ### ctx.fs.listDir(target, signal?) ```ts website-api abstract listDir(target: FsTarget, signal?: AbortSignal): Promise ``` List direct children of a directory in stable name order. Returns resolved child targets plus cheap metadata only; never reads file contents. - `target` — the resolved directory target. - `signal` — aborts the listing. **Returns** one entry per direct child, in stable name order. [Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L146) ### ctx.fs.writeText(target, content, expected?, signal?) ```ts website-api abstract writeText(target: FsTarget, content: string, expected?: FsWriteIntent, signal?: AbortSignal): Promise ``` Atomically create or replace UTF-8 text. `expected` guards intent and staleness; omission allows unconditional overwrite. - `target` — the resolved target to write. - `content` — the full new file content. - `expected` — the write intent guarding the write; omit for unconditional. - `signal` — aborts before the atomic rename takes effect. **Returns** the outcome, including the version the write produced. [Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L157) ### ctx.fs.editText(target, edit, expected?, signal?) ```ts website-api abstract editText(target: FsTarget, edit: FsEditRequest, expected?: { version: FsVersion }, signal?: AbortSignal): Promise ``` Atomically edit literal text. When supplied, the version guard is checked before matching so stale content reports `FS_STALE_VERSION`; omission edits the current content without a freshness precondition. - `target` — the resolved target to edit. - `edit` — the literal search/replace request. - `expected` — the version guard; omit for an unconditional edit. - `signal` — aborts before the atomic rename takes effect. **Returns** the outcome, including the version the edit produced. [Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L169)