# Conflicts: # .agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.i18n.yaml # .agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.md # .agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.zh.md # docs/capability-seams.md # docs/cordis-catalog/events.md # docs/cordis-catalog/services.md # docs/event-producer-consumer.md # docs/module-graph.md # docs/persistence-catalog.md # docs/rfc/INDEX.md # examples/acp-agent/README.md # examples/acp-agent/fs.cordis.snapshot.yml # examples/acp-agent/fs.cordis.yml # examples/acp-agent/tests/snapshots/escalation-approved/session.jsonl # examples/acp-agent/tests/snapshots/escalation-rejected/session.jsonl # examples/acp-agent/tests/snapshots/hook-cc-pretool-ask/session.jsonl # examples/acp-agent/tests/snapshots/permission-switching/session.jsonl # examples/acp-agent/tests/snapshots/workspace-context/system-prompt.expected.md # examples/acp-agent/tests/snapshots/workspace-context/tool-schemas.expected.json # examples/acp-agent/tests/snapshots/workspace-edit/system-prompt.expected.md # examples/acp-agent/tests/snapshots/workspace-edit/tool-schemas.expected.json # packages/bash/bash/src/index.ts # packages/bash/tool-bash/package.json # packages/bash/tool-bash/src/index.ts # packages/bash/tool-bash/tests/tools.spec.ts # packages/cordis/tool-cordis/src/api-catalog.ts # packages/fs/README.md # packages/fs/tool-fs/src/edit.ts # packages/fs/tool-fs/src/write.ts # packages/sandbox/README.md # pnpm-lock.yaml
237 lines
11 KiB
Markdown
237 lines
11 KiB
Markdown
<!-- Generated by scripts/gen-website-api.ts — do not edit by hand. Run `pnpm run gen-website-api` to regenerate. -->
|
|
|
|
# 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#L81)
|
|
|
|
### ctx.fs.sandboxMode
|
|
|
|
```ts website-api
|
|
/**
|
|
/**
|
|
* The sandbox mode this backend enforces on mutations BY DEFAULT, or
|
|
* `undefined` when it does not confine at all — the capability fact the tool
|
|
* layer reads to advertise the escalation fields honestly (mirrors
|
|
* `BashExecutor.sandboxMode`). The base class and the bare local backend
|
|
* report `undefined`; a sandboxing backend (`@deepseek-ai/dsh-fs-sandbox`)
|
|
* overrides it with the deployment default. A session override may make the
|
|
* effective mode narrower or wider, so strict escalation widening is checked
|
|
* per call rather than encoded in this default-relative fact.
|
|
* @returns the configured default mode of a sandboxing backend; `undefined`
|
|
* for a backend that never confines.
|
|
*/
|
|
get sandboxMode(): SandboxMode | undefined
|
|
```
|
|
|
|
/** The sandbox mode this backend enforces on mutations BY DEFAULT, or `undefined` when it does not confine at all — the capability fact the tool layer reads to advertise the escalation fields honestly (mirrors `BashExecutor.sandboxMode`). The base class and the bare local backend report `undefined`; a sandboxing backend (`@deepseek-ai/dsh-fs-sandbox`) overrides it with the deployment default. A session override may make the effective mode narrower or wider, so strict escalation widening is checked per call rather than encoded in this default-relative fact.
|
|
|
|
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L99)
|
|
|
|
### ctx.fs.resolve(path, opts?)
|
|
|
|
```ts website-api
|
|
/**
|
|
* Resolve a model/plugin-supplied path into a stable {@link 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.
|
|
*
|
|
* @param path - the path to resolve; relative paths resolve against `opts.cwd`.
|
|
* @param opts - optional cwd override and cancellation signal.
|
|
* @returns the stable target; the same file yields the same `targetKey`.
|
|
*/
|
|
abstract resolve(path: string, opts?: { cwd?: string; signal?: AbortSignal }): Promise<FsTarget>
|
|
```
|
|
|
|
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#L112)
|
|
|
|
### ctx.fs.stat(target, signal?)
|
|
|
|
```ts website-api
|
|
/**
|
|
* Return target metadata, or `undefined` when the target does not exist.
|
|
* @param target - the resolved target to stat.
|
|
* @param signal - aborts the metadata round-trip.
|
|
* @returns metadata only, never content; undefined for an absent target.
|
|
*/
|
|
abstract stat(target: FsTarget, signal?: AbortSignal): Promise<FsInfo | undefined>
|
|
```
|
|
|
|
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#L120)
|
|
|
|
### ctx.fs.lstat(path, opts?, signal?)
|
|
|
|
```ts website-api
|
|
/**
|
|
* Return path metadata without following the final path component when it is a
|
|
* symbolic link. This is intentionally path-shaped, not target-shaped:
|
|
* {@link 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 {@link resolve}'s cwd rules. `undefined` means the path is
|
|
* absent.
|
|
* @param path - the path to inspect; relative paths resolve against `opts.cwd`.
|
|
* @param opts - `cwd` overrides the backend's default base for relative paths.
|
|
* @param signal - aborts the metadata round-trip.
|
|
* @returns metadata only, never content; undefined for an absent path.
|
|
*/
|
|
abstract lstat(path: string, opts?: { cwd?: string }, signal?: AbortSignal): Promise<FsPathInfo | undefined>
|
|
```
|
|
|
|
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#L136)
|
|
|
|
### ctx.fs.readText(target, signal?)
|
|
|
|
```ts website-api
|
|
/**
|
|
* Read the whole regular text file as a single decoded string.
|
|
* @param target - the resolved target to read.
|
|
* @param signal - aborts the read.
|
|
* @returns the full decoded UTF-8 content.
|
|
*/
|
|
abstract readText(target: FsTarget, signal?: AbortSignal): Promise<string>
|
|
```
|
|
|
|
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#L144)
|
|
|
|
### ctx.fs.streamText(target, signal?)
|
|
|
|
```ts website-api
|
|
/**
|
|
* Stream the whole regular text file as decoded text chunks (same text
|
|
* semantics as {@link readText}, for large files). The backend owns
|
|
* cross-chunk UTF-8 decoding and binary rejection so the policy layer never
|
|
* touches raw bytes.
|
|
* @param target - the resolved target to read.
|
|
* @param signal - aborts the stream, including between chunks.
|
|
* @returns the chunk iterable, decoded and validated like {@link readText}.
|
|
*/
|
|
abstract streamText(target: FsTarget, signal?: AbortSignal): Promise<AsyncIterable<string>>
|
|
```
|
|
|
|
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#L155)
|
|
|
|
### ctx.fs.listDir(target, signal?)
|
|
|
|
```ts website-api
|
|
/**
|
|
* List direct children of a directory in stable name order. Returns resolved
|
|
* child targets plus cheap metadata only; never reads file contents.
|
|
* @param target - the resolved directory target.
|
|
* @param signal - aborts the listing.
|
|
* @returns one entry per direct child, in stable name order.
|
|
*/
|
|
abstract listDir(target: FsTarget, signal?: AbortSignal): Promise<FsDirEntry[]>
|
|
```
|
|
|
|
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#L164)
|
|
|
|
### ctx.fs.writeText(target, content, expected?, signal?, sandboxMode?)
|
|
|
|
```ts website-api
|
|
/**
|
|
* Atomically create or replace UTF-8 text. `expected` guards intent and
|
|
* staleness; omission allows unconditional overwrite.
|
|
* @param target - the resolved target to write.
|
|
* @param content - the full new file content.
|
|
* @param expected - the write intent guarding the write; omit for unconditional.
|
|
* @param signal - aborts before the atomic rename takes effect.
|
|
* @param sandboxMode - the per-call sandbox mode this write runs under; a
|
|
* sandboxing backend fences the write by it, the bare backend ignores it.
|
|
* Omit to leave the backend its own default.
|
|
* @returns the outcome, including the version the write produced.
|
|
*/
|
|
abstract writeText( target: FsTarget, content: string, expected?: FsWriteIntent, signal?: AbortSignal, sandboxMode?: SandboxMode, ): Promise<FsWriteOutcome>
|
|
```
|
|
|
|
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.
|
|
- `sandboxMode` — the per-call sandbox mode this write runs under; a sandboxing backend fences the write by it, the bare backend ignores it. Omit to leave the backend its own default.
|
|
|
|
**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#L178)
|
|
|
|
### ctx.fs.editText(target, edit, expected?, signal?, sandboxMode?)
|
|
|
|
```ts website-api
|
|
/**
|
|
* 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.
|
|
* @param target - the resolved target to edit.
|
|
* @param edit - the literal search/replace request.
|
|
* @param expected - the version guard; omit for an unconditional edit.
|
|
* @param signal - aborts before the atomic rename takes effect.
|
|
* @param sandboxMode - the per-call sandbox mode this edit runs under; a
|
|
* sandboxing backend fences the edit by it, the bare backend ignores it.
|
|
* Omit to leave the backend its own default.
|
|
* @returns the outcome, including the version the edit produced.
|
|
*/
|
|
abstract editText( target: FsTarget, edit: FsEditRequest, expected?: { version: FsVersion }, signal?: AbortSignal, sandboxMode?: SandboxMode, ): Promise<FsEditOutcome>
|
|
```
|
|
|
|
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.
|
|
- `sandboxMode` — the per-call sandbox mode this edit runs under; a sandboxing backend fences the edit by it, the bare backend ignores it. Omit to leave the backend its own default.
|
|
|
|
**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#L199)
|