docs: translate remaining READMEs

This commit is contained in:
Tianyi Cui
2026-07-26 05:03:53 +08:00
parent 37bfac749b
commit 226dc7a249
559 changed files with 11227 additions and 1 deletions

View File

@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
README.md: 140df90571d84320fb4eb888508c67e60aa29a22
README.zh.md: 4c16df2a56476c0a7c965a037389fa5ba231e273

View File

@@ -1,5 +1,7 @@
# util/ — low-level shared utilities
English | [中文](README.zh.md)
Zero-dependency primitives shared across the other groups. A package lands here when it owns a tiny, foundational type or helper that several capability families need but that belongs to none of them — keeping it out of any one group avoids a capability package depending on an unrelated one just to reach a shared primitive. These are **support** packages: small, stable, and free of harness dependencies.
| Package | Role |

View File

@@ -0,0 +1,20 @@
# util/:底层共享工具
[English](README.md) | 中文
其他分组共享的零依赖原语。当某个微小的基础类型或辅助工具被多个功能家族所需,但又不属于任何一个家族时,它就位于此处。这样可避免一个功能包仅为使用共享原语而依赖不相关的功能包。这些都是**支持** 包:规模小、稳定,且不依赖 harness。
| 包 | 职责 |
|---|---|
| `brand/` | 仅包含类型的 `Branded<B>` 名义类型原语(无运行时代码,无 harness 依赖) |
| `paths/` | 规范的单根 `DSH_HOME` 解析,以及 harness 用户数据的共享文件系统路径常量和辅助工具(无 harness 依赖) |
| `timeout/` | 超时的时序/分类部分:`clampTimeout`/`deadline`/`timeoutOf`/`TimeoutReason`(纯函数,无 harness 依赖);终止机制保留在各个功能中 |
| `retention/` | 有界的面向模型输出:`ItemRetainer`/`TextRetainer` 加上中性通知辅助工具(纯工具,无 harness 依赖);业务语义保留在各个工具中 |
`dsh-brand` 是规范示例:它只负责 `Branded<B>` 辅助工具,因此功能包可以为自己拥有的 id 添加品牌(`dsh-tasks``TaskId``dsh-session``SessionId` 等),而只需依赖 `dsh-brand`,无需仅为使用 `Branded` 而引入不相关的包。
`dsh-paths` 为每个包提供同一个可配置的 Harness 主目录,而不将这项横切事实归属给 bash、skill、telemetry 或组合 bundle。它优先解析显式值其次是 `$DSH_HOME`,最后回退到 `~/.dsh`返回绝对路径但不缓存、创建或修改任何内容。harness 将所有用户数据保存在同一根目录下。
`dsh-timeout` 对超时家族采用相同结构:`dsh-bash``dsh-web-fetch-local` 都只依赖 `dsh-timeout`,便可将调用方的取消与 deadline 融合,然后区分「已超时」和「已取消」。它刻意只负责时序/分类部分,*终止*机制(对进程组发送 SIGKILL、拆除 fetch socket保留在各个功能中因为没有任何共享层可以负责每个功能的终止操作见[超时库 Agent Note](../../.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.md))。
`dsh-retention` 对有界工具输出采用同样的拆分方式:工具(`glob`/`grep`/`bash`/`web_fetch`/`web_search`)将项或文本送入 retainer取回保留的内容以及被省略的精确内容分组、退出码、提供方错误和恢复文案则仍由工具负责。它刻意只负责保留机制`truncated` 是预算事实,绝不表示「检查不完整」状态(见[保留库 Agent Note](../../.agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.md))。

View File

@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
README.md: 68401d95a31ed2122386794ad5256a5cd93bb2a6
README.zh.md: c8b773937426487e67001bc133cf7fae3aea2c6e

View File

@@ -1,5 +1,7 @@
# dsh-brand
English | [中文](README.zh.md)
The `Branded<B>` nominal-typing primitive — a tiny, **type-only** package (no runtime code, no harness-package dependency) shared by every package that owns a cross-boundary id.
## What `Branded` is

View File

@@ -0,0 +1,28 @@
# dsh-brand
[English](README.md) | 中文
`Branded<B>` 名义类型原语:一个微小的**仅类型** 包(无运行时代码,无 harness 包依赖),由每个拥有跨边界 id 的包共享。
## `Branded` 是什么
品牌使 `SessionId``CallId` 这样结构相同的字符串在类型层面不可互换,尽管两者在运行时都是普通 `string`
```ts
import type { Branded } from '@deepseek-ai/dsh-brand'
export type SessionId = Branded<'SessionId'>
/** Brand a string as a SessionId (a plain cast — zero runtime cost). */
export function SessionId(id: string): SessionId {
return id as SessionId
}
```
构造操作通过所属包中针对每个 id 的工厂完成。比较、日志记录、JSON 序列化和协议格式与普通字符串表现相同;品牌会在编译时被擦除。
## 策略:为跨包边界的 id 添加品牌
包为自己拥有的 id 添加品牌:`CallId` 位于 `dsh-llm`,共享的 agent/会话 `SessionId` 位于 `dsh-session``TaskId` 位于 `dsh-tasks`。为可能被混淆的跨包 id 添加品牌,但无需为每个字符串都添加。
该包只负责原语。保持无依赖意味着,例如 `dsh-tasks` 可以为 `TaskId` 添加品牌,而无需仅为使用 `Branded` 而导入不相关的功能包。

View File

@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
README.md: b28e684f3183d739c8e229a9b341801dbf345d86
README.zh.md: 20cc033e4d0ee22d75c7ca315c462a7846146444

View File

@@ -1,5 +1,7 @@
# dsh-paths
English | [中文](README.zh.md)
Shared filesystem path helpers for DeepSeek Harness user data.
## DSH home

View File

@@ -0,0 +1,24 @@
# dsh-paths
[English](README.md) | 中文
DeepSeek Harness 用户数据的共享文件系统路径辅助工具。
## DSH 主目录
`resolveDshHome()` 解析 DeepSeek Harness 的单根主目录。优先级从高到低为:显式配置的路径、`$DSH_HOME``~/.dsh`。harness 将所有用户数据保存在同一根目录下。
`dshHomeDisplay()` 以符号方式表示当前根目录,用于面向用户的路径:默认主目录表示为 `~/.dsh`,任何已配置的主目录表示为 `$DSH_HOME`。它绝不会泄露机器的绝对路径。
`DSH_HOME_DIR_NAME` 定义默认用户数据目录名:`.dsh`
`defaultDshHome()` 使用 Node 的平台路径规则,将操作系统主目录与 `.dsh` 拼接,并返回默认 DeepSeek Harness 主目录。
`expandHomePath()` 使用操作系统主目录展开 `~``~/...` 和 Windows 风格的 `~\...` 前缀。它会保留非波浪号路径和 `~user/...` 原样不变。
该包刻意保持规模小且不依赖 harness以便产品包共享用户数据路径约定而不必彼此依赖。
## 已知限制与待完成工作
- **展开范围刻意保持狭窄**:只有单独的 `~``~/...``~\...` 使用当前操作系统主目录;`~alice/...` 等指定用户的形式、环境变量和 shell 表达式保持不变。
- **辅助工具不会操作文件系统**:调用方仍负责目录创建、存在性检查、权限,以及对结果路径应用信任策略。

View File

@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
README.md: d257075a67b35e92bce53a88fc6d002f4f4d5d9b
README.zh.md: 433d512144612137fbfccf107cfe0987cec091fa

View File

@@ -1,5 +1,7 @@
# dsh-retention
English | [中文](README.zh.md)
A dependency-light **retention** library: bounded model-facing output for tools that must cap how much context they return. A caller feeds items or text chunks into a bounded object, then gets the retained content plus exact omission metadata.
The library owns **only** the mechanical question *"what did we keep, and what did we omit?"*. Tool-specific code keeps its business semantics: file grouping, line numbering, exit codes, provider error states, per-line preview truncation, spill files, and the model-facing prose. This is the boundary the [Agent Note](../../../.agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.md) draws.

View File

@@ -0,0 +1,97 @@
# dsh-retention
[English](README.md) | 中文
一个轻依赖的**保留** 库:为必须限制返回上下文量的工具提供有界的面向模型输出。调用方将项或文本分片送入有界对象,然后取回保留的内容和精确的省略元数据。
该库**只** 负责这个机制问题:*「我们保留了什么,又省略了什么?」*。工具专用代码保留其业务语义文件分组、行号、退出码、提供方错误状态、每行预览截断、spill 文件以及面向模型的文案。这就是 [Agent Note](../../../.agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.md) 划定的边界。
它是**库,而非服务或插件**:没有 `ctx`,不注册任何内容,不发出任何事件。状态只存在于每个 retainer一次累积绝不跨调用。工具包直接导入它。
## 对外接口
```ts
import {
ItemRetainer, TextRetainer,
describeOmitted, formatRetentionNotice,
} from '@deepseek-ai/dsh-retention'
import type {
Omitted, PushDecision, RetainedItems, RetainedText,
ItemRetentionStrategy, TextRetentionStrategy, RetentionNotice,
} from '@deepseek-ai/dsh-retention'
```
| 导出项 | 职责 |
|---|---|
| `ItemRetainer<T>` | 限制有序逻辑单元路径、grep 匹配项、来源。v1 只支持 `head``push()``PushDecision``finish()``RetainedItems<T>`。 |
| `TextRetainer` | 限制面向字节的文本流。`head` / `tail` / `headTail`,并在 `finish()` 时保留 UTF-8 边界。`push()``PushDecision``finish()``RetainedText`。 |
| `describeOmitted(omitted, unit)` | 标准化的省略子句(`exact` 输出数量;`unknown` 不输出)。 |
| `formatRetentionNotice(notice, recovery)` | 将标准化的省略子句与工具自有的恢复指引连接起来。 |
| `Omitted` | `none` / `exact` / `unknown`:省略了多少内容。 |
| `PushDecision` | `{ kept, truncated }`:每次 push 的保留结果。 |
## 资源模式
两个 retainer 使用独立名称,而不是同一个通用收集器,因为它们的**资源模型** 不同。
- **`ItemRetainer` 限制有序逻辑单元**。搜索工具可收集完整结果集用于 spill 文件恢复,同时只为面向模型的预览保留前 `maxItems` 项。因为调用方会继续送入每个已观察到的项,所以省略数量是精确的。
- **`TextRetainer` 限制面向字节的文本**。`head``tail``headTail``finish()` 时保留 UTF-8 边界;`headTail``dsh-spill-policy` 用于围绕 spill 文件通知构建有界预览的形态。
## `truncated` 是预算事实,绝不表示「不完整」
`truncated` 表示*因为预算限制retainer 省略了本可获得的内容*。它**不** 表示上游不完整。权限失败、跳过二进制文件、提供方部分失败、不可读候选项和无效 UTF-8 保留在工具领域字段中,绝不合并到 `truncated`。将两者混为一谈是该库命名最容易诱发的缺陷;务必保持分离。
## 字节,而非字符
文本上限和 `omittedBytes` 按**字节** 计数,以保证进程/正文安全(子进程 pipe 和 HTTP 正文都是字节流)。跨越码点的分片会被正确处理:`finish()` 会修剪每个切割位置的不完整码点,使返回文本绝不在边界引入替换字符;首尾两侧会分开解码,因此绝不会跨越被省略的中间部分重建码点。按字符或行限制的预览预算属于独立的工具职责。
## 工具映射
当前每个保留消费方都按下表映射到该库。广泛迁移不属于该库首次落地的范围;下表是预期形态。
| 工具 | Retainer 与策略 | 说明 |
|---|---|---|
| `glob` | `ItemRetainer<FsGlobEntry>`, `head` | 收集完整的已排序路径列表用于 spill 文件,同时在内联位置保留第一页。路径映射、已跳过候选项和 `incomplete` 保留在外部。 |
| `grep` | `ItemRetainer<FlatGrepMatch>`, `head` | 收集匹配项用于 spill 文件,同时在内联位置保留第一页。每个匹配项的预览截断、分组、排序和 `incomplete` 保留在外部。 |
| `bash` | `TextRetainer`, `tail` or `headTail` | 执行器仍负责 spill 文件、退出状态、信号、超时和后台任务。 |
| `web_fetch` | `TextRetainer`, `head` or `headTail` | 提供方/资源上限保留为提供方事实retainer 只提供保留文本和省略元数据。 |
| `web_search` | `ItemRetainer<WebSearchSource>`, `head` | 当提供方返回的来源超过面向模型的结果应包含的数量时,标准化「来源已达上限」通知。 |
`read` **刻意不在 v1 范围内**。其 `read-render` 辅助工具负责文件专用的分页契约:`offset`/`limit`、行号、`totalLines`、偏移越界错误、每行预览截断、针对已选窗口的字节上限。这是行窗口渲染器,而非通用保留机制。单个 `Omitted` 数量无法表示行窗口两侧。
## 使用形态
```ts ignore-check
// glob: keep the first page inline while still collecting the full list for spill.
const retainer = new ItemRetainer<FsGlobEntry>({ kind: 'head', maxItems: globMaxResults })
const allEntries: FsGlobEntry[] = []
for await (const entry of candidates) {
allEntries.push(entry)
retainer.push(entry)
}
const { items, truncated, omitted } = retainer.finish()
// bash: keep a head + tail, read to process exit.
const out = new TextRetainer({ kind: 'headTail', headBytes: headCap, tailBytes: tailCap })
child.stdout.on('data', (chunk: Buffer) => { out.push(chunk) })
const { text, omittedBytes } = out.finish()
// A footer: the library standardizes the omission clause; the tool owns recovery words.
const footer = formatRetentionNotice(
{ scope: 'grep', strategy: 'head', unit: 'items', limit: grepMaxMatches, kept: items.length, omitted },
({ kept }) => `Results capped at ${kept}. Narrow the pattern, path, or include to see more.`,
)
```
## 模型体验
通过渲染保留内容和省略元数据的工具消费方间接影响模型。
#### KV 缓存影响
不直接导致失效;指定的消费方负责其引起的任何请求前缀变更。
## 已知限制与待完成工作
- **项保留只支持 `head`**tail、head/tail、分页、分组和提供方完整性语义仍由工具负责。
- **文本保留面向字节**`read` 分页等行窗口和字符窗口需要单独的渲染器;切割可能会丢弃部分 UTF-8 边界字节,以保持返回文本有效。

View File

@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
README.md: 11c55a45a1255e14fb551e42ba3965453dbd94ae
README.zh.md: 699fb62a4fa19f97d234f83b21f639f61a9f0777

View File

@@ -1,5 +1,7 @@
# dsh-timeout
English | [中文](README.zh.md)
The **timing-and-classification** half of a timeout — a zero-dependency library of pure functions (no runtime harness deps) shared by every capability that clamps a caller's timeout hint, arms a deadline, and later has to tell "timed out" apart from "cancelled".
It owns **no termination**. The signal it hands out only *notifies*; actually stopping the work stays in each capability, because that mechanism differs — bash SIGKILLs an OS process group, web tears down a `fetch` socket — and no shared layer can own all of them. This is the boundary the [Agent Note](../../../.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.md) draws: share the timing/classification, keep the hard kill local.

View File

@@ -0,0 +1,70 @@
# dsh-timeout
[English](README.md) | 中文
超时的**时序与分类** 部分:一个零依赖纯函数库(无运行时 harness 依赖),由每个需要限制调用方超时提示、启动 deadline并在之后区分「已超时」与「已取消」的功能共享。
它**不负责终止**。它发出的信号只会*通知*真正停止工作仍由各功能负责因为机制各不相同bash 对操作系统进程组发送 SIGKILLweb 拆除 `fetch` socket没有任何共享层能够承担全部终止机制。[Agent Note](../../../.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.md) 将边界划定为:共享时序/分类,将强制终止保留在本地。
它是**库,而非服务或插件**:没有 `ctx`,不注册任何内容,不持有状态,也不发出事件。「超时服务」必须了解如何停止每项功能的工作,这正是微内核要排除在共享层之外的知识。
## 对外接口
```ts
import { clampTimeout, deadline, idleWatchdog, MAX_TIMER_DELAY_MS, timeoutOf, TimeoutReason } from '@deepseek-ai/dsh-timeout'
```
| 导出项 | 职责 |
|---|---|
| `clampTimeout(requested, def, max, name?)` | 验证调用方可选的正有限提示,从 `def` 填充,并限制在 `max` 以内。如果提示不为正数或有限数,则抛出错误(包含 `name`)。 |
| `deadline(upstream, timeoutMs, code)` | 将 `upstream` 取消与超时融合为一个 `AbortSignal``AbortSignal.any`);超时携带 `TimeoutReason``[Symbol.dispose]` 清除 timer。 |
| `idleWatchdog(upstream, timeoutMs, code)` | 保持一个稳定的融合信号,并且只在受保护的异步迭代器 `next()` 尚未完成时启动。解析后取消启动后续需求重新启动dispose 清除;并发需求被拒绝。 |
| `MAX_TIMER_DELAY_MS` | Node 在不将延迟限制为 1 毫秒时可调度的最大延迟(`2_147_483_647`)。拥有 timer 的配置不得超过该值。 |
| `timeoutOf(signal \| { reason }, code?)` | 从已中止的信号/错误中恢复 `TimeoutReason`,否则返回 `undefined`,即超时与取消的分类器。传入 `code` 可仅匹配这个 deadline 的 timer见下文的嵌套。 |
| `TimeoutReason` | 印在超时中止上的内部原因(`code` + `timeoutMs`)。它不是公开错误;提供方将其转换为自己的错误/字段。 |
## `timeoutMs <= 0` 哨兵值
`0` 是后端自有后台工作bash `start()`)使用的「无超时」值,其可见范围为:**内部**。`deadline()` 不启动 timer只转发 `upstream`;如果也没有 upstream它将返回永不中止的信号和无操作 disposer因此每个调用方都能保持同一种调用形态。外部请求提示会通过 `clampTimeout` 验证为**正有限数**,之后才进入 `deadline`,因此 `0` 绝不是面向模型/插件的「禁用超时」值。
## 使用形态
```ts
import { deadline, timeoutOf } from '@deepseek-ai/dsh-timeout'
declare function runWork(options: { signal: AbortSignal }): Promise<unknown>
// Scope-lifetime consumer (foreground bash, one fetch): `using` disposes the timer.
export async function runWithDeadline(upstream: AbortSignal | undefined, timeoutMs: number): Promise<unknown> {
using d = deadline(upstream, timeoutMs, 'BASH_TIMEOUT')
const outcome = await runWork({ signal: d.signal }) // work listens on d.signal and terminates itself
const timedOut = timeoutOf(d.signal, 'BASH_TIMEOUT') !== undefined // classify the first abort, scoped to OUR code
const aborted = d.signal.aborted && !timedOut // mutually exclusive: timeout won, or cancel did
return { outcome, timedOut, aborted }
}
```
该信号只会*通知*;调用方必须连接自己的终止机制(`d.signal.addEventListener('abort', kill)`,或将 `d.signal` 传给 `fetch`)。让 promise 与 timer 竞速,会在子进程或 socket 泄漏的情况下就解析工具调用;发出信号则会强制要求存在真正的终止路径。
将你自己的 `code` 传给 `timeoutOf`,以便分类可在嵌套中组合:当你收到的 `upstream` *本身*就是 deadline 信号时(未来启动每次调用 deadline 的 `tools/execute` 中间件),如果外层 timer 首先触发,`AbortSignal.any` 会保留外层 `TimeoutReason`。将范围限定为你的 `code`,可将外部超时视为普通 upstream 取消,这才是你所属功能视角下的正确分类,而不会在本地 timer 尚未到期时就声称自己超时。
对于流式传输,创建一个 `idleWatchdog`,将其稳定的 `signal` 传入传输,并为每次提供方读取调用 `watchdog.next(iterator)`。间隔必须为正有限数,且不得超过 `MAX_TIMER_DELAY_MS`;否则 Node 会将其限制为 1 毫秒。它只测量尚未完成的需求因此当下游代码进行渲染或在请求下一个分片前以其他方式等待时timer 不会运行。该原语仍然只会通知因此传输必须观察稳定信号DeepSeek 和 pi-ai 适配器证明,超时会关闭它们的真实响应正文或 SDK 请求。
## 哪些操作不设置超时
本地文件 `read`/`write`/`edit` 不接受 `timeoutMs`:系统调用最多只能尽力中止,超时无法强制 `fsync`/`rename` 停止,而添加超时将成为违反显式优于隐式的默认值。详见 [`fs/`](../../fs/README.md)。
## 模型体验
通过 `dsh-timeout-policy` 等消费方间接影响模型;消费方可能会将提供方结果替换为已保留的超时错误,或抑制延迟结果。
#### KV 缓存影响
不直接导致失效;指定的消费方负责其引起的任何请求前缀变更。
## 已知限制与待完成工作
- **只发出通知**deadline 无法停止忽略其信号的工作;每项功能仍需要自己的 socket/进程/任务终止路径。
- **`timeoutMs <= 0` 是内部词汇**:只有在所属后端已解析策略后,它才会禁用本地 timer绝不会作为面向模型/插件的公开开关。
- **第一个中止原因决定分类**:当 upstream 取消早于本地 timer 发生时,即使自己的超时之后也会到期,该层也无法再报告。
- **空闲 watchdog 不是总 deadline**:它针对每个尚未完成的迭代器需求重新启动,并刻意排除消费方的思考时间。