website: generate the API reference from source (cordis + all 15 harness services)
scripts/gen-website-api.ts renders website/zh-CN/api/{cordis,harness}/* and the
api-sidebar.json fragment the VitePress config imports, so pages and navigation
can never drift from the code: signatures, @param/@returns prose, dispatch
modes, and GitHub source links are extracted, never transcribed, and the
generator hard-errors on any rendered member missing docs. verify-website-api
(doc-sync + run-gates) is the freshness gate.
Replaces the hand-written zh api pages (7 pages covering 7 of 15 services,
with phantom APIs: Context.current/Context.events, agent/post-step, tool/call,
compact/*, llm/pre-request none of which exist) with generated English
references: 5 cordis pages, 15 per-service pages, and a 35-event catalog
grouped by scope. The hand-written hub api/index.md stays and now indexes the
full surface; zh for these pages arrives with the unified translation flow.
This commit is contained in:
@@ -1,78 +1,126 @@
|
||||
# Filesystem (dsh-fs)
|
||||
<!-- Generated by scripts/gen-website-api.ts — do not edit by hand. Run `pnpm run gen-website-api` to regenerate. -->
|
||||
|
||||
文件系统操作接口。
|
||||
# ctx.fs
|
||||
|
||||
**接口包:** `@deepseek-ai/dsh-fs`
|
||||
**实现:** `@deepseek-ai/dsh-fs-local` + `@deepseek-ai/dsh-fs-policy`
|
||||
**消费者:** `@deepseek-ai/dsh-tool-fs`
|
||||
`FileSystem` (abstract seam) — provided by `@deepseek-ai/dsh-fs`.
|
||||
|
||||
## FS Service
|
||||
Abstract filesystem provider service. Subclass, implement the seven storage primitives, and load the subclass as a plugin — it registers as `ctx.fs` (one implementation per context; loading a second throws, cordis' standard duplicate-service behavior).
|
||||
Semantics every backend must honor:
|
||||
- resolve returns a stable FsTarget; the same underlying file reached by different input paths must yield the same `targetKey` so stale guards and target lookup agree across paths (e.g. through symlinks).
|
||||
- stat returns FsInfo metadata (never content) or `undefined` when the target is absent.
|
||||
- readText/streamText read the whole regular text file (the stream for large files); both own regular-file checks, UTF-8 decoding, binary/NUL rejection, and `FS_NOT_TEXT`.
|
||||
- listDir returns direct children of a directory in stable name order with resolved child targets and cheap metadata only. It never reads file contents. Missing targets throw `FS_NOT_FOUND`, non-directories throw `FS_NOT_DIRECTORY`, permission failures throw `FS_PERMISSION_DENIED`, and other backend I/O failures throw `FS_IO_ERROR`.
|
||||
- writeText is atomic temp-file + rename. `expected` is OPTIONAL: omit it for an unconditional create-or-overwrite (the bare-provider default), or supply a FsWriteIntent to guard the write.
|
||||
- editText verifies `expected.version` BEFORE literal matching (so a stale edit reports `FS_STALE_VERSION`, not `FS_EDIT_NOT_FOUND`/ `FS_AMBIGUOUS_EDIT` against newer content), then applies literal replacement and writes atomically — all inside one mutation critical section. `expected` is OPTIONAL: omit it for an unconditional edit of the current content (a missing target still reports `FS_STALE_VERSION`).
|
||||
|
||||
### ctx.fs.read(path, options?)
|
||||
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L172)
|
||||
|
||||
- **path:** `string`
|
||||
- **options:** `{ offset?: number; limit?: number }`
|
||||
- **返回值:** `Promise<string>`
|
||||
### ctx.fs.resolve(path, opts?)
|
||||
|
||||
读取文件内容。
|
||||
|
||||
### ctx.fs.write(path, content)
|
||||
|
||||
- **path:** `string`
|
||||
- **content:** `string`
|
||||
- **返回值:** `Promise<void>`
|
||||
|
||||
写入文件(覆盖)。
|
||||
|
||||
### ctx.fs.edit(path, edits)
|
||||
|
||||
- **path:** `string`
|
||||
- **edits:** `Edit[]`
|
||||
- **返回值:** `Promise<void>`
|
||||
|
||||
对文件执行精确的字符串替换编辑。
|
||||
|
||||
### ctx.fs.stat(path)
|
||||
|
||||
- **path:** `string`
|
||||
- **返回值:** `Promise<FileStat>`
|
||||
|
||||
获取文件/目录信息。
|
||||
|
||||
## 配置 (dsh-fs-local)
|
||||
|
||||
```typescript
|
||||
interface Config {
|
||||
/** 工作目录(相对路径的基准) */
|
||||
cwd: string
|
||||
}
|
||||
```ts website-api
|
||||
abstract resolve(path: string, opts?: { cwd?: string }): Promise<FsTarget>
|
||||
```
|
||||
|
||||
## 策略门 (dsh-fs-policy)
|
||||
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.
|
||||
`opts.cwd` is the base directory a RELATIVE `path` resolves against; an absolute `path` ignores it. Omitted ⇒ the backend's own default base (the local backend uses its configured `cwd`). The CALLER supplies this — the seam does not read a session or agent — so a tool can resolve against the caller's per-session workspace (`exec.agent.session.header.cwd`) without the provider depending on `dsh-agent`/`dsh-session`. Mirrors how `dsh-tool-bash` defaults a bash `workdir` to the session cwd.
|
||||
|
||||
`dsh-fs-policy` 是一个可选的中间层插件,实现 read-before-write/edit 策略——模型必须先读取文件才能写入或编辑。这防止模型盲目覆盖文件。
|
||||
- `path` — the path to resolve; relative paths resolve against `opts.cwd`.
|
||||
- `opts` — `cwd` overrides the backend's default base for relative paths.
|
||||
|
||||
在 `cordis.yml` 中,它位于 `fs-local` 和 `tool-fs` 之间:
|
||||
**Returns** the stable target; the same file yields the same `targetKey`.
|
||||
|
||||
```yaml
|
||||
- name: '@deepseek-ai/dsh-fs-local'
|
||||
config:
|
||||
cwd: !!js process.cwd()
|
||||
- name: '@deepseek-ai/dsh-fs-policy'
|
||||
- name: '@deepseek-ai/dsh-tool-fs'
|
||||
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L194)
|
||||
|
||||
### ctx.fs.stat(target, signal?)
|
||||
|
||||
```ts website-api
|
||||
abstract stat(target: FsTarget, signal?: AbortSignal): Promise<FsInfo | undefined>
|
||||
```
|
||||
|
||||
## 模型可用的 Tools
|
||||
Return target metadata, or `undefined` when the target does not exist.
|
||||
|
||||
| Tool | 说明 |
|
||||
|------|------|
|
||||
| `read` | 读取文件内容(支持 offset/limit) |
|
||||
| `write` | 写入文件(需要先 read) |
|
||||
| `edit` | 精确字符串替换(需要先 read) |
|
||||
- `target` — the resolved target to stat.
|
||||
- `signal` — aborts the metadata round-trip.
|
||||
|
||||
## 三件套结构
|
||||
**Returns** metadata only, never content; undefined for an absent target.
|
||||
|
||||
- `dsh-fs`:接口定义
|
||||
- `dsh-fs-local`:本地文件系统实现
|
||||
- `dsh-fs-policy`:策略门(read-before-write 检查)
|
||||
- `dsh-tool-fs`:模型 tool 层
|
||||
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L202)
|
||||
|
||||
### ctx.fs.readText(target, signal?)
|
||||
|
||||
```ts website-api
|
||||
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#L210)
|
||||
|
||||
### ctx.fs.streamText(target, signal?)
|
||||
|
||||
```ts website-api
|
||||
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 {@link readText}.
|
||||
|
||||
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/fs/fs/src/index.ts#L221)
|
||||
|
||||
### ctx.fs.listDir(target, signal?)
|
||||
|
||||
```ts website-api
|
||||
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#L230)
|
||||
|
||||
### ctx.fs.writeText(target, content, expected?, signal?)
|
||||
|
||||
```ts website-api
|
||||
abstract writeText(target: FsTarget, content: string, expected?: FsWriteIntent, signal?: AbortSignal): Promise<FsWriteOutcome>
|
||||
```
|
||||
|
||||
Create or fully replace a UTF-8 text file atomically. `expected` is the create-vs-replace decision and stale guard when supplied; OMITTING it is an unconditional create-or-overwrite (the bare provider — no version guard, no read-first requirement). Atomic either way.
|
||||
|
||||
- `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#L243)
|
||||
|
||||
### ctx.fs.editText(target, edit, expected?, signal?)
|
||||
|
||||
```ts website-api
|
||||
abstract editText(target: FsTarget, edit: FsEditRequest, expected?: { version: FsVersion }, signal?: AbortSignal): Promise<FsEditOutcome>
|
||||
```
|
||||
|
||||
Apply a literal edit to an existing UTF-8 text file. When `expected` is supplied, verifies `expected.version` as the stale guard BEFORE literal matching; OMITTING it edits the current content unconditionally (no version guard). Either way applies the replacement and writes atomically — one mutation critical section — and a missing target reports `FS_STALE_VERSION`.
|
||||
|
||||
- `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#L257)
|
||||
|
||||
Reference in New Issue
Block a user