): ContentBlock[] | undefined
+ /**
+ * Cooperative tool-call timeout budget in milliseconds. Omit for no deadline.
+ * Enforced by `@deepseek-ai/dsh-timeout-policy` (a `tools/execute` wrapper); it
+ * is NEVER sent to the model — `schemas()` whitelists only name/description/
+ * parameters. Declaring it asserts this tool forwards `exec.signal` to a
+ * cooperative implementation that can reach quiescence when the signal aborts.
+ */
+ timeoutMs?: number
+ /**
+ * Pure synchronous classifier for overlap with sibling tool calls. Only
+ * `true` opts in; omission, exceptions, non-`true` returns, and invalid
+ * `defineTool` arguments are exclusive. This metadata is never model-visible.
+ *
+ * Opted-in executions must not mutate parent-owned state. Shared state must
+ * tolerate concurrent dispatch; recorder races are permitted only when they
+ * commute or fail closed. See the
+ * [parallel-tool-call Agent Note](../../../../.agents/notes/implemented/feature/2026-07-10-parallel-tool-call-execution.md)
+ * for the full contract.
+ * @param args - parsed arguments; `defineTool` validates before calling.
+ * @returns Whether this call may join a parallel group.
+ */
+ isConcurrencySafe?(args: unknown): boolean
+ /**
+ * Optional: how to present the PENDING state of one call in a UI, derived from
+ * the call's `args` (parsed arguments, `unknown` — the tool validates/narrows
+ * its own input). Returns a {@link ToolCallView} (a `card`-tagged render intent),
+ * or `undefined` (or omit the method) to fall back to a generic presentation
+ * (title = tool name, raw args as input). Pure and side-effect-free: a UI may
+ * call it during live streaming AND a session-log replay, so it must depend
+ * only on `args`.
+ */
+ presentCall?(args: unknown): ToolCallView | undefined
+ /**
+ * Optional: how to present the COMPLETED state, given the same `args` and the
+ * durable result projection (`content`, failure state, and optional `meta`). Returns a
+ * {@link ToolResultView}, or `undefined` (or omit the method) to keep the
+ * pending title and render the raw result content. Pure and side-effect-free
+ * for the same replay reason.
+ */
+ presentResult?(args: unknown, result: ToolResult): ToolResultView | undefined
+}
+```
+
+`execute` 接收 `args: unknown`——原始的 `ToolDefinition` 自行校验输入。第一方工具不需要手写校验;它们使用 `defineTool`,由后者代为校验并收窄参数类型、根据 `output.schema` 推导函数体返回类型,并为两个输出投影器提供类型约束。`finalizeContent` 特意接收不可变的执行对象而非类型化参数,因为无效输入和外层流水线失败也会到达该回调;它可以施加工具自有的内容限制,同时保留 `isError`、规范值、结构化错误身份、延迟上下文与展示元数据。
+
+## 统一的 JSON 值 schema DSL
+
+插件作者使用同一套词汇描述类型化参数和类型化输出值。`ValueSchemaSpec` 支持 `string`、`number`、`integer`、`boolean`、`null`、`array`、`object`、仅作者侧可用的 `json`,以及要求恰好命中一个分支的 `oneOf`;标量 `enum` 和 `const` 值必须与节点类型匹配。显式对象节点始终声明 `additionalProperties: true | false`。参数定义仍是隐式的开放对象属性映射,每个必填属性都附带 `required: true`。
+
+源码:[`packages/core/tools/src/schema.ts`](../../packages/core/tools/src/schema.ts)
+
+```ts type-equiv
+/** One author-facing schema for any lossless JSON value root. */
+type ValueSchemaSpec =
+ | StringValueSchemaSpec
+ | NumberValueSchemaSpec
+ | IntegerValueSchemaSpec
+ | BooleanValueSchemaSpec
+ | NullValueSchemaSpec
+ | ArrayValueSchemaSpec
+ | ObjectValueSchemaSpec
+ | JsonValueSchemaSpec
+ | OneOfValueSchemaSpec
+```
+
+```ts type-equiv
+/** One implicit parameter-root property, optionally required. */
+type ParameterPropertySpec = ValueSchemaSpec & { required?: true }
+```
+
+```ts type-equiv
+/**
+ * Tool parameter schema. The map itself is an implicit open object root;
+ * requiredness remains a per-property `required: true` annotation.
+ */
+type ParameterSchemaSpec = {
+ [key: string]: ParameterPropertySpec
+ [key: symbol]: never
+}
+```
+
+`{ type: 'json' }` 推导为 `JsonValue`,并编译成仅含注解、不施加约束的原始 schema。输出根可以是对象、数组、标量或 null。`InferValue` 在 16 层容器内保留字面量约束与对象开放性,之后回退为 `JsonValue`,避免耗尽 TypeScript 的类型实例化栈。`InferArgs` 依据逐属性的必填标记生成必填和可选的字符串键:
+
+```ts type-equiv
+/**
+ * Infer the TypeScript value accepted by an author-facing value schema. Exact
+ * inference is bounded to 16 container levels, then falls back to `JsonValue`.
+ */
+type InferValue = InferValueAt
+```
+
+```ts type-equiv
+/** Infer the TypeScript argument object for an implicit parameter schema. */
+type InferArgs = InferProperties
+```
+
+`defineTool({ name, description, parameters, output, execute, … })` 将参数推导与 `parameterSchemaSpecToJsonSchema()` 和 `validateArgs()` 绑定,并将 `execute`/`render`/`presentationMeta` 与 `InferValue` 绑定。Schema 记录只包含自有且可枚举的字符串键,schema 数组是稠密的内建数组,因此推导、编译与校验观察到的是同一份声明。精确推导保持到 16 层容器,之后放宽为 `JsonValue`;运行时校验仍会继续遍历完整 schema。`valueSchemaSpecToJsonSchema()` 通过同一套已强制执行的原始子集编译输出声明。参数不匹配时抛出 `ToolArgsError`(`INVALID_ARGS`);函数体或后置策略产生的值无效时抛出 `ToolOutputError`(`INVALID_TOOL_OUTPUT`)。两者都经由常规工具错误路径处理。原始 JSON Schema 默认保持开放;不支持的关键字会被拒绝,而不会在未强制执行的情况下获准进入。
+
+注册是一个受信任的同进程契约。注册表以 readonly 输入借用类型化定义,要求它声明 `output`,校验其原始 schema,并检查 `timeoutMs` 必须为正有限值等语义要求;`schemas()` 在模型边界处物化显式的面向模型投影,使执行和展示共享同一份已解析定义,而不会将回调泄漏到协议上。
+
+## `ToolRestriction` — 单个作用域的实时全局过滤器
+
+`ToolRestriction` 仅作用于实时的部署全局工具层。注册表将 readonly 名称编译为私有集合,对多个限制取交集,再叠加作用域本地工具。仅 deny 的过滤器允许后续未列出的全局工具通过,而 allow 列表则排除它们。
+
+```ts type-equiv
+/**
+ * Per-scope filter over global tools. Restrictions intersect and do not affect
+ * scoped registrations or the reserved Code Mode transport.
+ */
+interface ToolRestriction {
+ /** Global tool names that stay visible; everything else is removed. */
+ readonly allow?: readonly string[]
+ /** Global tool names removed from visibility. */
+ readonly deny?: readonly string[]
+}
+```
+
+## 执行:可扩展的 waterfall(瀑布式事件)加单调策略
+
+`ctx.tools.execute()` 接受由调用方拥有且包含必需 readonly `signal` 的 `ToolExecutionInput`,将其解析后的 JSON 参数一次性物化为流水线拥有的 `ToolExecution`,然后让调用依次经过 `tools/pre-execute`(可重排的 allow/deny/ask waterfall)→ 已注册的单调 guard → `tools/execute`(环绕分派包装层)→ `tools/post-execute`(检查/替换结果)→ 可选且由定义拥有的 `finalizeContent` → `tools/result`(不可变的权威结果)。只有 `tools/execute` 视图可以替换必需的 signal。最终产出为 `ToolExecutionResult`。
+
+```ts type-equiv
+/** Opaque call identity that permits correlation without exposing mutable execution state. */
+type ToolExecutionToken = symbol & { readonly [toolExecutionTokenBrand]: true }
+```
+
+```ts type-equiv
+/**
+ * Caller-supplied description of one tool call. {@link ToolRegistry.execute}
+ * adds the registry-owned token to form a pipeline {@link ToolExecution};
+ * callers do not choose that token.
+ */
+interface ToolExecutionInput {
+ readonly callId: CallId
+ readonly name: string
+ /** Losslessly JSON-serializable parsed arguments (tools validate their own schema). */
+ readonly arguments: unknown
+ /** The agent on whose behalf the call runs (set by the agent loop). */
+ readonly agent?: Agent
+ /**
+ * Opaque token of the enclosing transport execution, when one exists. Code
+ * Mode sets this on SDK sub-dispatches so commit-style observers can wait for
+ * the outer `run_code` outcome without receiving its live mutable execution.
+ */
+ readonly parent?: ToolExecutionToken
+ /** Required caller-owned cancellation for this invocation. */
+ readonly signal: AbortSignal
+}
+```
+
+工具函数体接收运行时扩展。`deferContext()` 是组合工具的通道:它记录嵌套分派产生的上下文,而不会在外层调用尚未结束时注入这些上下文。
+
+```ts type-equiv
+/**
+ * Runtime context handed to a tool implementation after the registry has
+ * accepted a {@link ToolExecution}. A composite tool uses
+ * {@link deferContext} to ferry context produced by nested dispatches back to
+ * the outer result; the loop appends it only after the outer `tool/result`.
+ */
+interface ToolRunContext extends ToolExecution {
+ /**
+ * Defer one nested-dispatch context until this tool's final result reaches
+ * the agent loop. Contexts retain their individual source and metadata and
+ * are emitted in call order.
+ */
+ deferContext(context: HookContext): void
+}
+```
+
+agent loop(智能体循环)向注册表查询每个待处理调用的执行模式,并据此形成独占屏障和滚动池并行执行:
+
+```ts type-equiv
+/**
+ * Scheduling mode for one pending call. `parallel` may overlap with siblings;
+ * `exclusive` runs alone and forms an ordering barrier.
+ */
+type ToolExecutionMode =
+ | { kind: 'parallel' }
+ | { kind: 'exclusive' }
+```
+
+```ts type-equiv
+/**
+ * One pending tool call inside the registry pipeline. Parsed arguments cross
+ * one lossless-JSON materialization boundary before policy and are deep-frozen;
+ * call identity, the caller signal, and the registry-assigned {@link token} are
+ * readonly. The registry freezes the complete object before `tools/result`
+ * observers run.
+ */
+interface ToolExecution extends ToolExecutionInput {
+ /** Registry-assigned identity shared with nested calls only as their opaque `parent` token. */
+ readonly token: ToolExecutionToken
+}
+```
+
+```ts type-equiv
+/**
+ * Around-dispatch view of a {@link ToolExecution}. A `tools/execute` wrapper
+ * may replace the signal for its delegated lifetime, but it cannot remove it.
+ * The registry fuses every replacement with the captured caller signal.
+ */
+interface ToolDispatchExecution extends Omit {
+ /** Cancellation signal visible to the next wrapper or tool body. */
+ signal: AbortSignal
+}
+```
+
+`ToolExecutionToken` 是不透明的运行时 `Symbol`,仅用于身份比较。策略执行前,`execute()` 会物化并冻结参数、拒绝非 JSON 输入并分配 token。身份字段、调用方必需的 signal 和可选的 parent token 均保持 readonly。`ToolDispatchExecution` 包装层可以替换 signal 但不能移除;注册表会在调用工具函数体前重新融合调用方的 signal。最终观察者接收冻结的执行身份。
+
+`ToolGuard` 是感知作用域的最终预分派策略。其形状有意不包含 allow 结果:`undefined` 保留 waterfall 的决策,而返回的 reason 只能缩减权限,因此后续监听器无法撤销它。
+
+```ts type-equiv
+/**
+ * A monotonic execution guard evaluated after every `tools/pre-execute`
+ * listener and before the tool body. Returning a reason denies the call;
+ * returning `undefined` leaves it unchanged. Because guards have no allow
+ * result, listener ordering cannot turn a denial back into permission.
+ * @param execution - the identity-protected call after extensible pre-execute policy completed.
+ * @returns a final denial reason, or `undefined` to leave the call allowed.
+ */
+type ToolGuard = (execution: Readonly) => string | undefined
+```
+
+```ts type-equiv
+/** Canonical failure detail; internal routing information remains optional. */
+interface ToolFailure {
+ /** Human-readable failure message without the Native `Error: ` envelope. */
+ message: string
+ /** Internal error class/code used by policy and durable diagnostics. */
+ info?: ToolErrorInfo
+}
+```
+
+```ts type-equiv
+/** Successful canonical tool execution, including its Native/model projection. */
+interface ToolExecutionSuccess {
+ readonly isError: false
+ /** Execution-local canonical value; deliberately omitted from durable events. */
+ readonly value: JsonValue
+ readonly content: ContentBlock[]
+ readonly error?: never
+ readonly meta?: JsonValue
+ readonly additionalContexts?: HookContext[]
+}
+```
+
+```ts type-equiv
+/** Failed canonical tool execution; failures never carry a successful value. */
+interface ToolExecutionFailure {
+ readonly isError: true
+ readonly error: ToolFailure
+ readonly value?: never
+ readonly content: ContentBlock[]
+ readonly meta?: JsonValue
+ readonly additionalContexts?: HookContext[]
+}
+```
+
+```ts type-equiv
+/** The discriminated, execution-local outcome of one tool call. */
+type ToolExecutionResult = ToolExecutionSuccess | ToolExecutionFailure
+```
+
+结果仅承载产出。调用身份保留在不可变的 `ToolExecution` 上,后者伴随结果经过每个钩子,并出现在持久化的 `tool/call` / `tool/result` 会话事件上,因此包装层无法创建第二个相互矛盾的身份。规范的 `value` 仅存在于执行期间:循环只持久化 `content`、`error` 和 `meta`,`tool/code-dispatch` 则存储有界摘要。回放可以重现展示,却无法重建中间值。
+
+成功时,注册表会快照并校验函数体返回值,将其冻结,然后调用纯渲染器;对于直接的外层调用,还会调用可选的元数据投影器。注册表会在 `tools/result` 之前另行物化持久展示字段;无效值、渲染器/投影器失败或非 JSON 展示都会转为 JSON 安全的 `isError`。因此,最终实时观察者能看到精确的执行期值,以及可安全用于后续持久追加的字段。
+
+在得到最终内容之前,注册表会物化候选结果;若内容、结构化错误、附加上下文或展示元数据无法物化,则会转为仍可到达 `finalizeContent` 的 JSON 安全 `isError` 结果。注册表恰好调用该回调一次,随后在 `tools/result` 之前立即物化并冻结已接受的结果,因此实时观察到的产出可安全用于后续持久化的 `tool/result` 追加。
+
+每个拦截 waterfall 返回一个类型化的 **Decision**(与 `agent/*` seam 共享的惯用模式)。`tools/pre-execute` 监听器接收 `(exec, next)` 并返回 `PreToolDecision`;`tools/execute` 包装层返回 `ToolExecutionResult`;`tools/post-execute` 监听器接收 `(exec, result, next)` 并返回 `PostToolDecision`:
+
+```ts type-equiv
+/**
+ * Pre-dispatch decision. `allow` runs the call; `deny` materializes an error;
+ * `ask` runs only after an approval service returns `allowed-once` and otherwise
+ * denies. Input rewriting is excluded because arguments are already logged and
+ * presented.
+ */
+type PreToolDecision =
+ | { kind: 'allow' }
+ | { kind: 'deny'; reason: string }
+ | { kind: 'ask'; reason?: string }
+```
+
+```ts type-equiv
+/**
+ * Post-dispatch decision: accept, replace one projection, attach context for the
+ * next request, or block by turning corrective feedback into an error result.
+ */
+type PostToolDecision =
+ | { kind: 'accept'; content?: ContentBlock[]; value?: never; additionalContexts?: HookContext[] }
+ | { kind: 'accept'; value: JsonValue; content?: never; additionalContexts?: HookContext[] }
+ | { kind: 'block'; feedback: ContentBlock[]; additionalContexts?: HookContext[] }
+```
+
+调用 `next()` 获取默认决策,或直接返回一个决策以短路。前置策略可以 deny 或 ask;只有 `allowed-once` 才继续执行,而未授权、缺少审批通道或服务、或无 agent 的请求都会变为拒绝。Guard 仍可施加最终拒绝。参数不可被改写,因为历史记录、审计、UI 和执行必须保持一致。
+
+后置策略可以替换内容或值,但不能同时替换两者。替换内容会保留规范值和现有元数据;替换值会重新校验并重新计算内容/元数据;阻止会移除值,并转为包含纠正反馈的 `isError`。内容替换是展示策略,而非保密策略;需要隐藏程序化值的监听器必须阻止或替换该值。`tools/result` 在归一化后接收冻结的执行和结果;观察者无法对其进行变换,观察者的失败也会被隔离。未知工具和抛出异常的工具都会变为结构化错误(`ToolNotFoundError` 映射为 `UNKNOWN_TOOL`),调用失败但不终止当前轮次。
+
+## 已强制执行的原始 JSON Schema 子集
+
+subagent、工作流、MCP 和动态注册提供的原始 schema 使用作者侧 DSL 在协议层的对应表示。`assertSupportedJsonSchema()` 接受任意 JSON 根,`validateJsonSchemaValue()` 强制执行该 schema,`JsonSchemaError` 则报告每条不受支持或格式错误的 schema 路径。仅含注解的空节点表示不受约束的无损 JSON。`oneOf` 至少要求两个分支,且一个值必须恰好匹配其中一个。仍要求对象根的消费方调用 `assertObjectJsonSchema()` 并携带 `ObjectJsonSchema`;这样,subagent/工作流中由调用方定义的结构化输出可以继续以对象为根,而不会限制共享词汇。
+
+```ts type-equiv
+/** Scalar JSON values supported by `enum` and `const`. */
+type JsonSchemaScalar = string | number | boolean | null
+```
+
+```ts type-equiv
+/** Single-type keywords accepted by the enforced subset. */
+type JsonSchemaType = 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null'
+```
+
+```ts type-equiv
+/**
+ * One raw JSON Schema node in the enforced subset. The optional fields express
+ * the external wire shape; {@link assertSupportedJsonSchema} rejects invalid
+ * combinations before a caller treats the node as trusted.
+ */
+interface JsonSchemaNode {
+ /** Omit with no constraints for any JSON value, or use `oneOf`. */
+ type?: JsonSchemaType
+ /** Exactly one branch must validate; at least two branches are required. */
+ oneOf?: JsonSchemaNode[]
+ /** Nested property schemas (`type: 'object'` only). */
+ properties?: Record
+ /** Required property names; each must appear in `properties`. */
+ required?: string[]
+ /** `false` rejects undeclared keys; absent/`true` follows JSON Schema's open default. */
+ additionalProperties?: boolean
+ /** Item schema (`type: 'array'` only); absent accepts any JSON item. */
+ items?: JsonSchemaNode
+ /** Allowed values for a scalar node. */
+ enum?: JsonSchemaScalar[]
+ /** The single allowed value for a scalar node. */
+ const?: JsonSchemaScalar
+ /** Annotation, ignored for validation. */
+ description?: string
+ /** Annotation, ignored for validation. */
+ title?: string
+ /** Annotation, ignored for validation but required to be lossless JSON. */
+ default?: JsonValue
+ /** Annotation, ignored for validation but required to be lossless JSON. */
+ examples?: JsonValue
+}
+```
+
+```ts type-equiv
+/** A consumer-constrained object-rooted schema. */
+type ObjectJsonSchema = JsonSchemaNode & { type: 'object' }
+```
+
+## 工具展示 UI 词汇
+
+工具希望其调用在 UI 中如何呈现(编辑器工具调用卡片、CLI(命令行界面)日志行),提供方无关,使工具在不依赖任何客户端协议的情况下描述自身。`presentCall`/`presentResult` 返回一个 **`card` 标签的渲染意图**——一个可辨识联合类型,UI 桥接层据此分发:
+
+- `ToolCallView`(待执行):`{ card: 'generic', title, kind?, rawInput?, content?, locations? }`(默认卡片;`locations` 是 `{ path, line? }[]`,表示调用读取/修改的文件,供编辑器跟随)、`{ card: 'terminal', title, description?, cwd? }`(shell 命令→终端卡片)、或 `{ card: 'diff', title, diffs, locations? }`(文件创建/修改→行内 diff 卡片;`diffs` 是 `{ path, oldText, newText }[]`,新文件时 `oldText: null`)。
+- `ToolResultView`(已完成):`{ card: 'generic', title?, content? }`、`{ card: 'terminal', title?, output?, exitCode?, signal? }`(捕获的运行输出 + 退出状态;有能力的 UI 显示退出状态标签,无能力的 UI 获得桥接层从 `output` 派生的围栏 ` ```console ` 回退)、或 `{ card: 'diff', title?, diffs }`(已完成的文件变更→要展示的变更,通常是从变更前后内容计算出带上下文行的已应用 hunk,或在没有前像时的整文件 diff——例如文件创建。`tool_call_update` 的内容会替换调用的内容,因此变更工具即使与调用时的片段重复也要返回此卡片,以防结果文本覆盖 diff)。
+
+`ToolCallKind`(`'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'fetch' | 'other'`)用于为通用卡片选择图标。`FileLocation`(`{ path, line? }`)与 `FileDiff`(`{ path, oldText, newText }`)是共享的文件卡片词汇。该设计由[渲染意图联合类型 Agent Note(agent 决策记录)](../../.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.md)固定;ACP(Agent Client Protocol)桥接层将 `diff` 卡片映射为 `{ type: 'diff' }` 内容块,将 `terminal` 卡片映射为 `_meta` 终端约定,并根据会话 cwd 将文件卡片标题转换为相对路径。
+
+完整的展示字段文档见 [`packages/core/tools/src/presentation.ts`](../../packages/core/tools/src/presentation.ts)。`bash` schema 与执行器见 [bash.md](bash.md);通用后台控制见 [tasks.md](tasks.md)。
diff --git a/docs/core-data-structures/user-interaction.i18n.yaml b/docs/core-data-structures/user-interaction.i18n.yaml
new file mode 100644
index 0000000000..126f18729e
--- /dev/null
+++ b/docs/core-data-structures/user-interaction.i18n.yaml
@@ -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
+user-interaction.md: 7ddc2f46bdbbe25f2a8979b029d0c6b958f85b09
+user-interaction.zh.md: 75b9b7795a36e0706672f0d17ba0b399c20cc644
diff --git a/docs/core-data-structures/user-interaction.md b/docs/core-data-structures/user-interaction.md
index e010b48987..7ddc2f46bd 100644
--- a/docs/core-data-structures/user-interaction.md
+++ b/docs/core-data-structures/user-interaction.md
@@ -1,5 +1,7 @@
# User Interaction
+English | [中文](user-interaction.zh.md)
+
The user-interaction seam of [dsh-user-interaction](../../packages/ui/user-interaction). It is the provider-neutral vocabulary a tool or permission plugin uses when it needs the human to answer before the agent can continue. UI surfaces provide the active `UserInteractionProvider`: `dsh-tui` uses keyboard-driven overlays, and `dsh-acp` maps questions to ACP form elicitations.
Source: [`packages/ui/user-interaction/src/index.ts`](../../packages/ui/user-interaction/src/index.ts)
diff --git a/docs/core-data-structures/user-interaction.zh.md b/docs/core-data-structures/user-interaction.zh.md
new file mode 100644
index 0000000000..75b9b7795a
--- /dev/null
+++ b/docs/core-data-structures/user-interaction.zh.md
@@ -0,0 +1,108 @@
+# 用户交互
+
+[English](user-interaction.md) | 中文
+
+[dsh-user-interaction](../../packages/ui/user-interaction) 的用户交互 seam。它是工具或权限插件需要人类回答后 agent(智能体)才能继续时所使用的、提供方无关的词汇。UI surface 提供活跃的 `UserInteractionProvider`:`dsh-tui` 使用键盘驱动的 overlay,`dsh-acp` 则把问题映射为 ACP(Agent Client Protocol)表单 elicitation。
+
+源码:[`packages/ui/user-interaction/src/index.ts`](../../packages/ui/user-interaction/src/index.ts)
+
+## 问题选项
+
+`AskUserQuestionOption` 是可选择项的形状。`label` 是面向用户的选项文字,同时也是面向模型的选中值;`description` 是可选的 UI 帮助文本。
+
+```ts type-equiv
+/** One selectable answer offered to the user. */
+interface AskUserQuestionOption {
+ /** User-facing label. */
+ label: string
+ /** Optional extra context rendered by capable UIs. */
+ description?: string
+}
+```
+
+## 问题条目
+
+`AskUserQuestionItem` 是请求中的一个问题。调用方提供稳定的 `id`,它会随答案原样返回,使批量问题仍可路由。可选的 `detail` 携带辅助文本;提供方会将其随问题渲染,但不会放入可选 option label。
+
+```ts type-equiv
+/** One question in a user-interaction request. */
+interface AskUserQuestionItem {
+ /** Stable caller-provided question id, echoed in the answer. */
+ id: string
+ /** The question to display. */
+ question: string
+ /** Optional supporting detail rendered with the question but kept out of option labels. */
+ detail?: string
+ /** Optional short heading/group label. */
+ header?: string
+ /** Optional choices the UI can render as a menu. */
+ options?: AskUserQuestionOption[]
+ /** Whether more than one option may be selected. Defaults to single-select. */
+ multiSelect?: boolean
+}
+```
+
+## 提问请求
+
+`AskUserQuestionRequest` 是跨包(package)的请求。`questions` 是数组,这样 UI 可以在一个流程中呈现相关提示,同时保持每个回答有稳定的 id。
+
+```ts type-equiv
+/** Request for a human answer. */
+interface AskUserQuestionRequest {
+ /** Questions to display. */
+ questions: AskUserQuestionItem[]
+ /** Calling agent, when the request came from an agent tool call. */
+ agent?: Agent
+ /** Abort signal for the owning tool/step. */
+ signal?: AbortSignal
+}
+```
+
+## 回答
+
+提供方为每个问题 id 返回一个回答项。`selected` 包含选中的选项标签,`custom` 在用户输入自由文本时携带「其他」回答。当 `custom` 存在时,`selected` 为空;自定义文本是对选中项的覆盖,而非补充。UI 也可以使用 `selected` 为空且不含 `custom` 的回答项,在其余问题均已完成的批次中保留被跳过的问题。
+
+```ts type-equiv
+/** Answer to one question. */
+interface AskUserQuestionAnswerItem {
+ /** The answered question id. */
+ id: string
+ /** Selected option labels. Empty for custom or unanswered choices. */
+ selected: string[]
+ /** Optional free-text "Other" answer. */
+ custom?: string
+}
+```
+
+```ts type-equiv
+/** The human's answer. */
+interface AskUserQuestionAnswer {
+ /** Structured answers keyed by question id. */
+ answers: AskUserQuestionAnswerItem[]
+}
+```
+
+## 提供方
+
+同一上下文中只能有一个活跃的提供方。提供方注册绑定到 effect,因此 HMR(热模块替换)或 dispose(资源释放)会移除当前活跃的 UI。
+
+```ts type-equiv
+/** UI-side provider for user questions. */
+interface UserInteractionProvider {
+ ask(request: AskUserQuestionRequest): Promise
+}
+```
+
+## 错误
+
+`UserInteractionError` 继承 `HarnessError`,因此 `ctx.tools.execute()` 会保留 `{ name, code }`,用于面向模型的工具失败,如 `EMPTY_QUESTIONS`、`NO_PROVIDER`、`ASK_ABORTED` 或 ACP 侧取消。
+
+```ts type-equiv
+/** Stable error taxonomy for user-interaction failures. */
+class UserInteractionError extends HarnessError {
+ constructor(message: string, code: string, options?: ErrorOptions) {
+ super(message, code, options)
+ this.name = 'UserInteractionError'
+ }
+}
+```
diff --git a/docs/core-data-structures/web.i18n.yaml b/docs/core-data-structures/web.i18n.yaml
new file mode 100644
index 0000000000..912c1decbe
--- /dev/null
+++ b/docs/core-data-structures/web.i18n.yaml
@@ -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
+web.md: 20d07240c9d9fea2f1f5abbac810f349a3e81f9b
+web.zh.md: 68ceed04bb0b80f32ed704118f1fc25f48a0da70
diff --git a/docs/core-data-structures/web.md b/docs/core-data-structures/web.md
index 22909b8dfb..20d07240c9 100644
--- a/docs/core-data-structures/web.md
+++ b/docs/core-data-structures/web.md
@@ -1,5 +1,7 @@
# Web Access
+English | [中文](web.zh.md)
+
The web access seam — a [capability seam](../../.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.md) that spans **two capabilities** (search and fetch) on one `ctx.web` service, split across packages: interface ([dsh-web](../../packages/web/web), `ctx.web` + the provider registries), implementations ([dsh-web-search-exa](../../packages/web/web-search-exa), [dsh-web-search-perplexity](../../packages/web/web-search-perplexity), [dsh-web-search-deepseek](../../packages/web/web-search-deepseek), [dsh-web-fetch-local](../../packages/web/web-fetch-local)), and consumer ([dsh-tool-web](../../packages/web/tool-web), the `web_search`/`web_fetch` tool schemas). Web is **one optional capability**, not part of the agent-loop spine — so its vocabulary lives here, not in [core.md](core.md). A search-provider swap does not change how the model asks for a query, and a fetch-implementation swap does not change how the model asks for a URL.
Source: [`packages/web/web/src/types.ts`](../../packages/web/web/src/types.ts)
diff --git a/docs/core-data-structures/web.zh.md b/docs/core-data-structures/web.zh.md
new file mode 100644
index 0000000000..68ceed04bb
--- /dev/null
+++ b/docs/core-data-structures/web.zh.md
@@ -0,0 +1,135 @@
+# Web 访问
+
+[English](web.md) | 中文
+
+Web 访问 seam 是一个[能力 seam](../../.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.md),在同一个 `ctx.web` 服务上横跨**两项能力**(search 与 fetch),并拆分到多个包(package):接口([dsh-web](../../packages/web/web),`ctx.web` + 提供方注册表)、实现([dsh-web-search-exa](../../packages/web/web-search-exa)、[dsh-web-search-perplexity](../../packages/web/web-search-perplexity)、[dsh-web-search-deepseek](../../packages/web/web-search-deepseek)、[dsh-web-fetch-local](../../packages/web/web-fetch-local))与消费方([dsh-tool-web](../../packages/web/tool-web),即 `web_search`/`web_fetch` 工具 schema)。Web 是**一项可选能力**,不属于 agent loop(智能体循环)主干,因此其词汇定义在此而非 [core.md](core.md) 中。更换 search 提供方不会改变模型请求 query 的方式,更换 fetch 实现也不会改变模型请求 URL 的方式。
+
+源码:[`packages/web/web/src/types.ts`](../../packages/web/web/src/types.ts)
+
+## 为什么两项能力合为一个 seam
+
+搜索与抓取既不共享请求 schema,也不共享业务逻辑,但它们被有意设计为同一个 `ctx.web` 中间层:一个提供方选择策略的所有者、一套 abort/error 词汇、一个面向产品的「此 harness 如何访问 Web」配置界面。代价是服务上并行的 `searchX`/`fetchX` 方法对;这种并行是有意为之,而非遗漏的提取。提供方注册的是**能力**(`WebSearchProvider` 或 `WebFetchProvider`),而非工具;面向模型的名称、schema、提示词引导与展示全部集中在唯一的消费方 `dsh-tool-web` 中。
+
+## 搜索请求与结果
+
+面向模型的工具参数仅为一个 `query`;`maxResults` 是消费方自有的上限(`dsh-tool-web` 的 `searchMaxResults` 配置,默认 `8`),通过 seam 传递并在返回时强制执行——如果提供方返回超量,seam 截断 `sources[]` 并设置 `truncated`。
+
+```ts type-equiv
+/**
+ * What one search-capable backend can return. The model-facing argument is just
+ * a query; `maxResults` is a `dsh-tool-web`-layer bound passed through unchanged
+ * and enforced on the way back by the seam (see {@link WebSearchResult}).
+ */
+interface WebSearchRequest {
+ readonly query: string
+ /**
+ * Upper bound on returned sources; the seam truncates to it. Omitted = no
+ * bound. `dsh-tool-web` always sets it. A provider whose API supports a
+ * result-count control (Exa's `numResults`) should apply it at the request
+ * layer as a cost/latency optimization; the seam enforces the bound
+ * regardless.
+ */
+ readonly maxResults?: number
+}
+```
+
+```ts type-equiv
+/**
+ * Normalized search outcome. `content` is optional provider-generated answer
+ * text or summary (Exa returns none; Perplexity returns a generated answer).
+ * `sources[]` is the portable citation surface. `truncated` is set by the seam
+ * when it cut `sources[]` down to `maxResults`.
+ */
+interface WebSearchResult {
+ /** Optional provider-generated answer text, search context, or summary. */
+ readonly content?: string
+ /** Citeable sources, already truncated to the request's `maxResults`. */
+ readonly sources: readonly WebSearchSource[]
+ /** True when the seam dropped sources to honor `maxResults`. */
+ readonly truncated: boolean
+}
+```
+
+`content` 是提供方可选生成的回答文本(Exa 和 DeepSeek 不返回;Perplexity 返回生成式回答)。`sources[]` 是一套可跨提供方使用的引用数据结构。一个 source 必有 `url`;`title`/`snippet`/`publishedAt` 可选,因为并非每个提供方都返回它们——Perplexity 的引用可能只有 URL,强迫适配器编造其余字段会让 seam 说谎。`dsh-tool-web` 渲染时使用 `title ?? hostname(url)`。
+
+```ts type-equiv
+/**
+ * One citeable source. A source always has a URL; `title`, `snippet`, and
+ * `publishedAt` are optional because not every provider returns them — forcing
+ * adapters to invent them would make the seam lie (Perplexity citations may be
+ * URL-only). `dsh-tool-web` renders `title ?? hostname(url)` for display.
+ */
+interface WebSearchSource {
+ readonly url: string
+ readonly title?: string
+ readonly snippet?: string
+ /** Publication/crawl timestamp as a provider-supplied ISO-8601 string. */
+ readonly publishedAt?: string
+}
+```
+
+## 抓取请求与结果
+
+```ts type-equiv
+/**
+ * What one fetch-capable backend is asked to retrieve. The request deliberately
+ * omits timeout, format, prompt, and extraction controls: cancellation is a
+ * direct execution argument, while presentation and higher-level LLM concerns
+ * belong outside safe retrieval.
+ */
+interface WebFetchRequest {
+ readonly url: string
+}
+```
+
+HTTP 状态码是被抓取资源状态的一部分,不自动视为失败:成功的网络抓取返回 `404`/`500` 时,仍产出一个带状态码和有界解码 body 的 `WebFetchResult`。`url` 是经过允许的重定向后的最终 URL。`WebError` 仅用于无法安全获取或表示资源的情况。
+
+```ts type-equiv
+/**
+ * Normalized fetch outcome. A successful network fetch of a non-2xx response is
+ * a result, not an error: the status code is part of the fetched resource
+ * state. {@link WebError} is reserved for failures to safely retrieve or
+ * represent the resource.
+ */
+interface WebFetchResult {
+ /** The final URL after allowed redirects (the request URL is in the request). */
+ readonly url: string
+ /** HTTP status code of the fetched response. */
+ readonly statusCode: number
+ /** Decoded body, classified by content kind. */
+ readonly body: WebFetchBody
+ /** True when the provider capped the decoded body. */
+ readonly truncated: boolean
+}
+```
+
+`WebFetchBody` 是 `dsh-web` 拥有的**封闭**可辨识联合类型(不是可合并扩展的 map):提供方解码 kind,`dsh-tool-web` 渲染它,因此新增一个 kind 是已知包之间的协调变更,而非插件扩展。消费方对 `kind` 做 `switch` 并以 `default: assertNever(...)` 结尾,所以新增 kind 会在每个消费方处编译失败,直到被处理。即使各分支当前字段一致,每个分支仍保持独立的对象字面量,为将来分支特有字段留出空间(例如未来 `pdf` body 的 `pageCount`)。
+
+```ts type-equiv
+/**
+ * The decoded body of a fetched resource. A CLOSED discriminated union owned by
+ * `dsh-web`: the provider decodes the kind and `dsh-tool-web` renders it, so a
+ * new kind is a coordinated change across known packages, not a plugin
+ * extension. Consumers `switch` on `kind` ending in `default: assertNever(...)`
+ * so adding a kind breaks compilation at every consumer until handled. Each arm
+ * stays its own object literal even where fields coincide today, leaving room
+ * for arm-specific fields later (a `pdf` body's `pageCount`).
+ */
+type WebFetchBody =
+ | { readonly kind: 'html'; readonly content: string }
+ | { readonly kind: 'text'; readonly content: string }
+```
+
+## 提供方可用性
+
+提供方的 `available(): boolean` 是一个廉价的本地检查(凭证是否存在、配置是否可解析),**禁止发起网络调用**。它是执行时选择的输入,而非健康检查系统:`search()`/`fetch()` 读取它以选出可用的提供方,选择失败以结构化的 `WebError` 呈现给调用方路由——其 code 和 message 携带可分支的细节(缺失的 id 或有歧义的候选集)。
+
+选择从不依赖注册顺序、配置顺序或 HMR(热模块替换)顺序:一项能力要么有显式的提供方 id(配置 `searchProvider`/`fetchProvider`,或填充同一字段的对应环境变量),要么在恰好只有一个可用提供方注册时自动选择;多个可用提供方且未配置 id 时为 `WEB_PROVIDER_AMBIGUOUS`,而非先注册先赢。
+
+## 错误
+
+`WebError extends HarnessError`([core.md](core.md) 错误分类体系),带有 `code: string`(开放式,与其他 seam 的错误一致——`LlmError`、`SubagentError`),而非封闭联合类型:提供方可以在不修改 `dsh-web` 的情况下抛出自己的 code,消费方必须容忍未知 code。code 按所有者划分。seam 中立的 code 由 `WebService` 选择逻辑和共享契约抛出:`WEB_PROVIDER_UNAVAILABLE`、`WEB_PROVIDER_CONFIGURED_MISSING`、`WEB_PROVIDER_CONFIGURED_UNAVAILABLE`、`WEB_PROVIDER_AMBIGUOUS`、`WEB_DUPLICATE_PROVIDER`(注册时的编程错误,类似 `LlmService` 的 `DUPLICATE_ADAPTER`)、`WEB_ABORTED`,以及 `WEB_PROVIDER_ERROR`(提供方自身故障通过 seam 暴露的兜底 code,包括网络/传输失败——DNS、连接被拒、TLS)。抓取传输层 code 由 `dsh-web-fetch-local` 实现拥有,不同的抓取后端无需抛出它们:`WEB_INVALID_URL`、`WEB_BLOCKED_URL`、`WEB_REDIRECT_BLOCKED`、`WEB_FETCH_TOO_LARGE`、`WEB_FETCH_TIMEOUT`、`WEB_UNSUPPORTED_CONTENT_TYPE`。
+
+## 服务
+
+`WebService` 注册搜索与抓取提供方,以 `WEB_DUPLICATE_PROVIDER` 拒绝重复 id,并在执行时以结构化的选择错误解析提供方。本地抓取后端仅接受 HTTP(S)、拒绝凭证、限制重定向次数、字节数、字符数和时间、对每一跳同源重定向重新校验,并解码 body;展示由工具负责。私有网络阻断尚未实现,因此请勿在可触及敏感内部目标的环境中启用 `web_fetch`。
diff --git a/docs/core-data-structures/workflow.i18n.yaml b/docs/core-data-structures/workflow.i18n.yaml
new file mode 100644
index 0000000000..492a9bea08
--- /dev/null
+++ b/docs/core-data-structures/workflow.i18n.yaml
@@ -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
+workflow.md: 8d271b89e71de6f6bef548aa8da61402ef9ada6e
+workflow.zh.md: b8ed699eb52d9f0cef23c513f625de7e82c46c45
diff --git a/docs/core-data-structures/workflow.md b/docs/core-data-structures/workflow.md
index 8d8e47fc79..8d271b89e7 100644
--- a/docs/core-data-structures/workflow.md
+++ b/docs/core-data-structures/workflow.md
@@ -1,5 +1,7 @@
# Workflow
+English | [中文](workflow.zh.md)
+
The workflow seam — an agent running a model-written orchestration SCRIPT that fans out subagents. Like [subagent](subagent.md) it is **one optional capability**, not part of the agent-loop spine, so its vocabulary lives here rather than in [core.md](core.md). Unlike the subagent registry it takes the bash shape: ONE engine implementation per context provides `ctx.workflows`; there is no named-provider registry (a second engine is a plugin swap, not a co-resident).
Interface: [dsh-workflow](../../packages/workflow/workflow) (`ctx.workflows` + the vocabulary below). The implementation is [dsh-workflow-workerthread](../../packages/workflow/workflow-workerthread) (a `node:worker_threads` engine — one worker per run, the script's vm context inside it); the model-facing consumer is [dsh-tool-workflow](../../packages/workflow/tool-workflow). The proposal and rationale: [the dynamic-workflows Agent Note](../../.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.md).
diff --git a/docs/core-data-structures/workflow.zh.md b/docs/core-data-structures/workflow.zh.md
new file mode 100644
index 0000000000..b8ed699eb5
--- /dev/null
+++ b/docs/core-data-structures/workflow.zh.md
@@ -0,0 +1,132 @@
+# 工作流
+
+[English](workflow.md) | 中文
+
+工作流 seam:一个 agent(智能体)运行由模型编写的编排脚本(SCRIPT),扇出 subagent。与 [subagent](subagent.md) 一样,它是**一项可选能力**,不属于 agent loop(智能体循环)主干,因此其词汇定义在此处而非 [core.md](core.md)。与 subagent 注册表不同,它采用 bash 形态:每个上下文只有一个引擎实现提供 `ctx.workflows`;没有命名提供方注册表(第二个引擎是插件替换,而非共存)。
+
+接口:[dsh-workflow](../../packages/workflow/workflow)(`ctx.workflows` + 下文词汇)。实现是 [dsh-workflow-workerthread](../../packages/workflow/workflow-workerthread)(一个 `node:worker_threads` 引擎——每个 run 一个 worker,脚本的 vm 上下文位于其中);面向模型的消费方是 [dsh-tool-workflow](../../packages/workflow/tool-workflow)。提案与设计理由见 [dynamic-workflows Agent Note(agent 决策记录)](../../.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.md)。
+
+源码:[`packages/workflow/workflow/src/types.ts`](../../packages/workflow/workflow/src/types.ts)
+
+## 启动请求
+
+调用方启动 run 时提出的请求。普通工作流工具根据模型的 `{ script, meta, args }` 调用与发起调用的 agent 构建它;专用消费方还可以为该 run 选择一个引擎级 `subagentProvider` 并调低 `maxTotalAgents`,但脚本无法观察或替换这两项策略。`meta` 与 `args` 是普通 JSON 数据(引擎会对 `meta` 做形状校验,并在任何内容运行前大声拒绝——绝不会通过求值脚本文本来获取它)。`parent` 是必填字段——脚本生成的每个子 agent 都归属于它(cwd、谱系与深度通过 [subagent seam](subagent.md) 流转)。
+
+```ts type-equiv
+/**
+ * What a caller asks for when starting a workflow run. `meta` and `args` are
+ * plain JSON DATA by the seam contract (the tool builds both from the model's
+ * schema-validated call; the engine validates `meta`'s shape and rejects loud
+ * before anything runs) — an engine never evaluates script text to obtain
+ * them. `parent` is REQUIRED — every `agent()` the script spawns is
+ * attributed to it (cwd, lineage, depth flow through the subagent seam).
+ */
+interface WorkflowStartRequest {
+ /** The plain-JS script body (top-level await allowed; ends with `return `). */
+ script: string
+ /** The workflow's identity block, as plain JSON data (shape-validated by the engine). */
+ meta: WorkflowMeta
+ /** Optional input exposed verbatim to the script as the `args` global. */
+ args?: unknown
+ /**
+ * Optional engine-wide child-provider override for this run. The workflow
+ * script cannot observe or replace it; omission uses the engine's configured
+ * provider.
+ */
+ subagentProvider?: string
+ /**
+ * Optional per-run total-child ceiling. Implementations reject values above
+ * their deployment ceiling before publishing the run.
+ */
+ maxTotalAgents?: number
+ /** The agent on whose behalf the run executes (parent of every child). */
+ parent: Agent
+ /** Cancels the run when aborted (the tool's `exec.signal`). */
+ signal?: AbortSignal
+}
+```
+
+## 工作流的身份标识:`WorkflowMeta`
+
+作为数据附在启动请求上的身份块(工具的 `meta` 参数;字段词汇与 Claude Code 动态工作流的 meta 块一致)。`phases` 仅用于进度展示:`phase()` 调用与标题匹配,供观察者使用;不暗示任何执行结构。
+
+```ts type-equiv
+/**
+ * The script's identity block, provided as plain JSON data alongside the
+ * script body (the model-facing tool carries it as its `meta` parameter) and
+ * validated by the engine before the body runs. `name`/`description` are
+ * required; the rest is optional annotation. The field vocabulary matches the
+ * Claude Code dynamic-workflows meta block.
+ */
+interface WorkflowMeta {
+ /** Short kebab-case workflow name (display + persistence key). */
+ name: string
+ /** One-line description of what the workflow does. */
+ description: string
+ /** Optional guidance on when this workflow applies (shown in listings). */
+ whenToUse?: string
+ /** Optional phase declarations matched by `phase()` calls. */
+ phases?: WorkflowPhase[]
+}
+```
+
+## 终态结果:`WorkflowResult`
+
+一次运行的结果,由 `WorkflowRun.result` resolve。`value` 是脚本的物化返回值——纯宿主域 JSON 数据(脚本无返回值时为 `null`)——仅在 `completed` 时有意义。`stopReason` 是封闭联合类型(引擎所有;消费方可穷举):`completed` | `cancelled` | `error`。非 `completed` 的原因在 `error` 中携带失败信息,消费方将其映射为 `isError` 工具结果,而非把部分输出当作成功上报。
+
+```ts type-equiv
+/**
+ * The outcome of one run, resolved by {@link WorkflowRun.result}. `value` is
+ * the script's materialized return value (plain host-realm JSON data; `null`
+ * when the script returned `undefined`) — meaningful only for `completed`.
+ * A non-`completed` reason carries the failure in `error`; the consumer maps
+ * it to an `isError` tool result rather than reporting partial output.
+ */
+interface WorkflowResult {
+ /** The script's return value (host JSON data; `null` for no return). */
+ value: unknown
+ /** Why the run settled. */
+ stopReason: WorkflowStopReason
+ /** The failure message (present iff `stopReason` is not `completed`). */
+ error?: string
+ /**
+ * How many `agent()` calls the run accepted over its whole lifetime. On a
+ * graceful settlement this is the script-side count (calls still queued for
+ * a concurrency slot included); on a termination path (grace force-settle,
+ * worker death) it degrades to the host-observed count — calls queued
+ * inside a terminated script are unknowable then.
+ */
+ agentsStarted: number
+}
+```
+
+## 活跃运行:`WorkflowRun`
+
+脚本执行期间消费方持有的句柄。消费方 await `result`,可中途 `cancel`,且必须在每条路径上 `dispose`(资源释放)。`result` 不会 reject:脚本失败以 `stopReason: 'error'` resolve;一旦运行被取消,即使脚本本身永不 settle,它也会在引擎的有界宽限期内 settle(引擎强制以 `cancelled` settle;worker-thread 引擎随后终止脚本的 worker),因此消费方 await `result` 不会在取消后卡死。`dispose()` = cancel + 有界 settle + 等待子 agent 停稳;它不会因脚本卡死而挂起。
+
+```ts type-equiv
+/**
+ * Holder-owned live workflow. `result` never rejects and settles within the
+ * engine's cancellation grace; failures resolve through `stopReason`. Consumers
+ * may cancel and must call idempotent `dispose()` on every path to await bounded
+ * script settlement and child quiescence.
+ */
+interface WorkflowRun {
+ readonly id: WorkflowRunId
+ /** The validated meta block (available before the body runs). */
+ readonly meta: WorkflowMeta
+ readonly result: Promise
+ /** Cancel the run: children abort, pending hooks reject, the script dies at its next await (or is force-settled at the grace). */
+ cancel(reason?: string): void
+ /** Cancel + bounded-grace settle; safe to call on every path (idempotent). */
+ dispose(): Promise
+}
+```
+
+## 失败纪律:`WorkflowError.fatal`
+
+脚本内部的钩子误用:错误参数、未知或延迟的 `agent()` 选项、超出[结构化输出子集](../../packages/core/tools/README.md)的 schema、触发的上限、seam 启动失败、取消,都会抛出 `fatal: true` 的 `WorkflowError`。`parallel()`/`pipeline()` 组合器对 fatal 错误直接重新抛出,而非将该项映射为 `null`:一个拼写错误的选项必须让脚本大声失败,绝不能消融为看似普通子 agent 失败的结果。逐项的 `null` 保留给子运行失败(非 `completed` 的 stop reason)和阶段内的普通脚本错误。
+
+## 事件
+
+`workflow/*` 事件(`workflow/start`、`workflow/phase`、`workflow/log`、`workflow/agent-start`、`workflow/agent-end`、`workflow/end`,见[事件目录](../cordis-catalog/events.md))是**仅供观察**的 emit,携带数据快照:每个 payload 以 `WorkflowRunInfo`(id + meta)开头,而非活跃的 `WorkflowRun`,因此订阅者无法获得 `cancel`/`dispose`;`workflow/end` 刻意省略 result value(观察结果的监听器不得收到调用方 result 的可变别名)。每次 emit 对每个监听器隔离:抛出异常的订阅者被记录日志但不传播,不会饿死在它之后注册的监听器;每个监听器收到自己的 payload 克隆,因此修改它既不会损坏引擎也不会影响其他监听器。这种隔离方式与 `subagent/start`/`subagent/end` 一致。
diff --git a/docs/postmortem/0001-acp-default-export-drops-inject.i18n.yaml b/docs/postmortem/0001-acp-default-export-drops-inject.i18n.yaml
new file mode 100644
index 0000000000..d48af64198
--- /dev/null
+++ b/docs/postmortem/0001-acp-default-export-drops-inject.i18n.yaml
@@ -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
+0001-acp-default-export-drops-inject.md: ab3efc880cb5290dc149b6bacb276ccf581968c1
+0001-acp-default-export-drops-inject.zh.md: 763b2e6230cf42dcd6985df3d7e2da8766176fd5
diff --git a/docs/postmortem/0001-acp-default-export-drops-inject.md b/docs/postmortem/0001-acp-default-export-drops-inject.md
index 10e88c390c..ab3efc880c 100644
--- a/docs/postmortem/0001-acp-default-export-drops-inject.md
+++ b/docs/postmortem/0001-acp-default-export-drops-inject.md
@@ -1,5 +1,7 @@
# Post-mortem 0001: ACP server crashed on connect — `export default` dropped the plugin's `inject`
+English | [中文](0001-acp-default-export-drops-inject.zh.md)
+
Status: resolved (fix in PR #41 `feat/acp-2-bridge`)
## Executive summary
diff --git a/docs/postmortem/0001-acp-default-export-drops-inject.zh.md b/docs/postmortem/0001-acp-default-export-drops-inject.zh.md
new file mode 100644
index 0000000000..763b2e6230
--- /dev/null
+++ b/docs/postmortem/0001-acp-default-export-drops-inject.zh.md
@@ -0,0 +1,113 @@
+# 事故复盘(postmortem) 0001:ACP(Agent Client Protocol)服务器在连接时崩溃——`export default` 丢弃了插件的 `inject`
+
+[English](0001-acp-default-export-drops-inject.md) | 中文
+
+Status: resolved (fix in PR(Pull Request) #41 `feat/acp-2-bridge`)
+
+## 摘要
+
+两个集成错误在单元测试全覆盖的情况下仍然导致 ACP 崩溃:一个 default export 使 Loader 丢弃了 `inject`,一个经 traceable 代理的可选服务查找在 shadow 边界上失败。手动挂载的测试绕过了这两条路径。修复方案增加了无需 API key 的真实 Loader 覆盖率,并为插件导出和可选服务访问制定了包(package)级规则。
+
+## 概述
+
+ACP 服务器(`examples/acp-agent`、`@deepseek-ai/dsh-acp`)在真实编辑器(Zed)连接的瞬间崩溃:第一个 `session/new` 请求返回 `Internal error: cannot get property "agents" without inject`,`session/load` 对 `sessionPersistence` 返回同样的错误。尽管有 178 个绿色单元测试和 100% 行覆盖率,bridge 在生产环境中完全无法工作。两个独立的 bug 隐藏在同一个错误字符串背后,测试套件之所以两个都没捕获,原因也相同:所有测试都通过一条不会触及插件真实加载方式和服务真实解析方式的路径来挂载插件。
+
+## 影响
+
+ACP 服务器无法创建或加载任何一个会话——而这正是编辑器最先调用的两个 RPC。任何将 agent(智能体)接入 Zed 的人都会立即遭遇硬性失败。无数据丢失(崩溃前没有任何内容被持久化);代价完全是「功能不可用」加上两次定位原因的调试时间。
+
+## 时间线
+
+- bridge(RFC 010)落地时附带完整的单元测试套件(codec、内存传输、基于属性的协议形状测试、失败路径、HMR(热模块替换))、一个需要 key 的真实 API e2e 测试,以及一个无需 key 的 stdout 纯净性 e2e 测试。全部绿色,100% 覆盖率。
+- 真实 Zed 会话在 `session/new` 上立即失败,报错 `cannot get property "agents" without inject`。
+- 调查最初追踪了一个 Cordis「traceable/shadow」理论(看似合理,且该机制确实存在——见 Bug #2),随后在 vendor 的 `reflect.ts` 中对实际 fiber 遍历做了插桩,并运行了真实子进程。trace 显示 throw 发生在 `apply()` 第 179 行、*插件加载时*,位于 ROOT fiber 且没有 shadow——推翻了 shadow 理论对 `session/new` 的解释。
+- 找到根因 #1:一行多余的 `export default apply`。删除后 `session/new` 修复。
+- 删除后暴露了 Bug #2:`session/load` 仍然在 `sessionPersistence` 上抛错——这是一个真正不同的机制(shadow 遍历),通过隔离修复并重新运行真实子进程得到确认。
+
+## 根因 #1——`export default apply` 丢弃了插件的 `inject`(导致 `session/new` 崩溃)
+
+`packages/ui/acp/src/index.ts` 是一个*命名空间插件*:它将 `name`、`inject`、`Config` 和 `apply` 作为独立的命名导出——与仓库中其他所有插件(`invariants`、`llm-deepseek`、`tool-bash`、`tui` 等)形状相同。但它*还*多了一行其他插件都没有的代码:
+
+```ts ignore-check
+export const name = 'acp'
+export const inject = ['agents', 'sessions', 'sessionPersistence']
+export function apply(ctx: Context, config: AcpConfig): void { /* … */ }
+// …
+export default apply // ← the bug
+```
+
+当插件从 `cordis.yml` 加载时,Cordis Loader 通过 `Loader.unwrapExports`(`vendor/loader/src/index.ts`)对导入的模块进行规范化:
+
+```ts ignore-check
+unwrapExports(exports: any) {
+ if (isNullable(exports)) return exports
+ exports = exports.default ?? exports // ← prefers `.default`
+ if (!exports.__esModule) return exports
+ return exports.default ?? exports
+}
+```
+
+存在 default export 时,`exports.default ?? exports` 解析为**裸 `apply` 函数**。裸函数没有 `inject`、没有 `name`、没有 `Config` 属性——这些作为*兄弟*命名导出存在于模块命名空间上,而 unwrap 到 `.default` 把整个命名空间丢弃了。Loader 随后基于空的 `inject` 构建了插件的 fiber。
+
+因此 `apply` 在一个**没有注入任何服务**的 fiber 中运行。第一行 `const agents = ctx.agents` 遍历 fiber 树(ROOT → Include → Loader → ROOT),在所有 fiber 的 store 中都找不到 `agents`,到达根 fiber(`runtime === null`)后抛出 `cannot get property "agents" without inject`。崩溃发生在*加载时*,而非后续的请求处理器中——请求只是恰好触发了加载。
+
+**修复:** 删除 `export default apply`。Loader 随后使用模块命名空间,正确识别 `inject`/`name`/`Config`,`apply` 在一个真正授予了声明服务的 fiber 中运行。
+
+## 根因 #2——可选服务读取通过 traceable shadow 触发 inject 守卫(导致 `session/load` 崩溃)
+
+修复 #1 后,`session/new` 正常工作,但 `session/load` 仍然抛出 `cannot get property "sessionPersistence" without inject`。这个问题*确实*是 Cordis 的 traceable/shadow 机制,值得精确理解。
+
+`session/load` 调用 `agents.resume(...)`,后者委托给 `AgentLoop.resume()`,其中读取了 `this.ctx.sessionPersistence`。`AgentLoop` 的 `static inject` 故意不包含 `sessionPersistence`——注入它会导致非持久化的演示永远挂起,等待一个永远不会加载的后端。该服务由一个独立的兄弟插件/fiber 提供,以机会性方式读取。
+
+Cordis 中的服务访问通过上下文代理(`vendor/cordis/src/reflect.ts`)进行。当通过从外部 fiber 获取的 *traceable 代理*调用服务方法时(此处:bridge fiber 调用 `ctx.agents.resume`,注册表返回 `this.factory`——即 `AgentLoop`——重新包装为绑定到调用方的新 traceable 代理),`createShadowMethod`(`vendor/cordis/src/utils.ts`)将 `this` 重新绑定到一个 *shadow* 对象,其 `ctx` 携带 `[symbols.shadow]` 指向 `AgentLoop` 自身的构造上下文。在 `resume` 内部,`this.ctx.sessionPersistence` 的解析从 shadow 的 fiber 开始遍历:
+
+```ts ignore-check
+// reflect.ts get handler
+let fiber = (ctx[symbols.shadow] as Context ?? ctx).fiber // ← starts at AgentLoop's fiber
+while (true) {
+ const impl = fiber.store?.[prop]
+ if (impl) return getTraceable(ctx, impl.value)
+ if (prop in fiber.inject) { /* inactive-context error */ }
+ if (!fiber.runtime) throw error // ← reached root, throw
+ if (fiber.parent[symbols.isolate][prop] !== key) throw error
+ fiber = fiber.parent.fiber // ← ancestor-only
+}
+```
+
+遍历**仅向祖先方向**进行。`sessionPersistence` 既不在 `AgentLoop` 的 fiber store 中(不在其 `static inject` 中),也不在通往 root 的任何祖先上(它位于一个*兄弟*分支),因此遍历到达根 fiber 后抛错。
+
+为什么内存中的 `AgentLoop` 恢复测试没有捕获这个问题?因为它们从测试代码直接调用 `ctx.agents.resume(...)`——*在任何插件 fiber 之外*。此时 `ctx.fiber.runtime` 为 `null`,代理处理器走了一条提前绕过的路径:
+
+```ts ignore-check
+if (!ctx.fiber.runtime) return ctx.reflect.get(prop, false) // ← direct global-store lookup, no fiber walk
+```
+
+`ctx.reflect.get(name, false)` 是基于 isolate symbol 的全局服务 store 直接查找——完全忽略 fiber 拓扑,能找到服务。因此从顶层测试读取可以成功;而从真实插件 fiber 内部、经由 shadow 到达时则抛错。bridge 恰好是后者。
+
+**修复:** 使用 `ctx.get('sessionPersistence')` 读取可选服务,该方法使用全局 isolate-keyed store 同时保留活跃状态检查。对于插件声明注入集中的服务,直接属性读取仍然适用。
+
+## 为什么所有测试都没有捕获(真正的失败)
+
+两个 bug 共享同一个流程缺口:**没有任何测试通过插件的真实加载路径或真实调用拓扑来驱动它。**
+
+- 内存 harness 通过手动构建插件对象来挂载 bridge:`ctx.plugin({ name, inject, apply })`。这手动提供了 `inject`,因此永远无法复现 Bug #1——`unwrapExports` 只被 *Loader* 调用,`ctx.plugin` 从不调用它。即使 `ctx.plugin(NamespaceImport)` 也无法捕获。
+- 同一个 harness 将所有内容平铺挂载在一个根上下文上,因此从中触达的 `AgentLoop` 恢复要么运行在顶层(`!runtime` 绕过),要么通过一个 origin 仍然解析在 root 上的 shadow——掩盖了 Bug #2 的祖先遍历失败。
+- 唯一的无 key e2e 发送 `initialize` 并检查 stdout 纯净性。`initialize` 从不触达 factory,因此两个 bug 都安然通过。
+- 唯一驱动 `session/new`/`session/load` 的测试需要 key 才能运行,因此 CI(无 key)跳过了它——而本地它之所以「通过」,只是因为一个陈旧的已构建 `lib/`(包含旧代码)恰好满足了模块解析。
+
+100% 行覆盖率始终满足。覆盖率证明代码行*被执行过*;它不能说明功能是否*按交付方式正常工作*。
+
+## 新增的防护措施
+
+- **删除 `export default apply`**(`packages/ui/acp/src/index.ts`)——Bug #1 的修复。
+- **`AgentLoop.resume` 使用 `this.ctx.get('sessionPersistence')`**(`packages/core/agent-loop/src/index.ts`)——Bug #2 的修复,附注释说明 shadow 遍历陷阱。
+- **无需 key 的 `session/new` e2e,通过真实 stdio 运行**(`examples/acp-agent/tests/acp.e2e.ts`):以子进程方式通过真实 Loader 启动示例,并断言 `session/new` 正常返回。无需 API key 即可在 Bug #1 上大声失败。已验证恢复 `export default apply` 时测试失败。
+- **e2e spawn 中设置 `TSX_TSCONFIG_PATH`**:子进程从临时 cwd 运行,tsx 无法通过向上搜索找到仓库根的 tsconfig `paths` 映射——因此 dsh-* 的 import 静默回退到已构建的 `lib/`。将 tsx 指向仓库 tsconfig 使解析不依赖 cwd,确保测试运行的是*源码*而非可能陈旧的构建产物。
+- **[docs/testing.md](../testing.md) 规则**:「测试真实入口路径」,行覆盖率不等于行为覆盖率——将这一教训编纂为所有未来插件的规则。
+
+## 经验教训
+
+- 命名空间插件与 default export 在 Cordis Loader 下互斥。选择命名空间形式(`name`/`inject`/`Config`/`apply`),不要添加 `export default`——`unwrapExports` 会丢弃命名空间。
+- 对于插件机会性读取但未在 `static inject` 中声明的服务,使用 `ctx.get(name)`,绝不使用 `ctx.`。属性代理通过仅向祖先方向的 fiber 遍历解析,经由外部 shadow 时会失败;`ctx.get(name)` 是拓扑无关的查找(且默认严格——非活跃后端读取为 `undefined`,而非在 teardown 过程中被交出)。
+- 手动构建插件的测试无法验证插件的加载方式。至少一个测试必须端到端地驱动真实的 Loader/export 路径。当核心操作不调用模型时,该测试无需 API key——因此它属于 CI,而非 key 门控之后。
+- 相信 trace,不要相信理论。优雅的 shadow 解释是真实的,但它是*第二个* bug;*第一个*是一行导出错误,在数小时看似合理但实际错误的推理之后,一个 fiber 遍历的 `console.error` 在几分钟内就找到了它。
diff --git a/docs/postmortem/0002-js-expression-disabled-filesystem-tools.i18n.yaml b/docs/postmortem/0002-js-expression-disabled-filesystem-tools.i18n.yaml
new file mode 100644
index 0000000000..2aad7141c5
--- /dev/null
+++ b/docs/postmortem/0002-js-expression-disabled-filesystem-tools.i18n.yaml
@@ -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
+0002-js-expression-disabled-filesystem-tools.md: 30ff9d920821a8d55c4bea5f120f1aeeca6634b3
+0002-js-expression-disabled-filesystem-tools.zh.md: b103ec6de5d6d6406ba48ec34f6ebb479e472352
diff --git a/docs/postmortem/0002-js-expression-disabled-filesystem-tools.md b/docs/postmortem/0002-js-expression-disabled-filesystem-tools.md
index ccdb725bfb..30ff9d9208 100644
--- a/docs/postmortem/0002-js-expression-disabled-filesystem-tools.md
+++ b/docs/postmortem/0002-js-expression-disabled-filesystem-tools.md
@@ -1,5 +1,7 @@
# Post-mortem 0002: Filesystem snapshot tools were permanently disabled
+English | [中文](0002-js-expression-disabled-filesystem-tools.zh.md)
+
Status: resolved
## Executive summary
diff --git a/docs/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md b/docs/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md
new file mode 100644
index 0000000000..b103ec6de5
--- /dev/null
+++ b/docs/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md
@@ -0,0 +1,47 @@
+# 事故复盘(postmortem) 0002:文件系统快照工具被永久禁用
+
+[English](0002-js-expression-disabled-filesystem-tools.md) | 中文
+
+Status: resolved
+
+## 摘要
+
+ACP(Agent Client Protocol)示例试图通过 `disabled: !!js ...` 有条件地启用文件系统插件,但 Cordis 仅在插件 `config` 内部对 JavaScript 表达式求值。原始的表达式对象为 truthy,因此文件系统栈始终处于禁用状态。快照刷新随后将 `UNKNOWN_TOOL` 结果接受为新的预期输出。修复方案改用显式的文件系统 overlay,并增加了静态配置守卫和快照结果守卫。
+
+## 概述
+
+默认的 ACP 组合有意只启用 bash,因为其沙箱无法约束进程内的文件系统提供方。文件系统快照场景仍然需要 `read`、`write` 和 `edit`,因此这些插件被放在默认的 `cordis.yml` 中,并附带一个 `disabled` 表达式,意图仅在全权限启动和快照模式下启用它们。
+
+Cordis Include 将每个 `!!js` 标量解析为一个表达式对象。Loader 递归地对插件的 `config` 进行插值,但直接消费 `disabled` 等入口元数据。因此每个文件系统入口看到的都是一个 truthy 对象,在所有模式下均保持禁用。
+
+## 影响
+
+七个文件系统场景和一个混合工作区编辑场景调用了注册表中不存在的工具。其结构化会话日志携带 `ToolNotFoundError`(code 为 `UNKNOWN_TOOL`),stdout 渲染出通用的失败工具卡片。快照套件通过了,因为结构化会话日志和 stdout 渲染出的通用失败工具卡片均与刷新后的 fixture(测试前置数据)匹配;它证明的是回归的确定性回放,而非文件系统行为的正确性。
+
+实际运行的受限默认模式并未获得意外的文件系统访问权限。一个简单的插值修复反而会制造该风险:权限预设在运行时更新 bash 沙箱和审批状态,但无法挂载、卸载或约束文件系统栈。
+
+## 时间线
+
+- PR(Pull Request) #261 整合了 ACP 组合并刷新了文件系统快照,同时引入了条件式文件系统入口。
+- 所有单元测试、覆盖率、快照、文档、构建和 hygiene 检查均通过。
+- 对刷新后的文件系统预期输出的评审发现了通用的失败卡片和结构化的 `UNKNOWN_TOOL` 结果。
+- 一次真实的 Loader 启动确认:每个 `disabled` 值仍为表达式对象,每个文件系统 fiber 均未创建。
+
+## 根因
+
+实现时假设 `!!js` 适用于整个 Loader 入口。其实际边界更窄:`Entry._resolveConfig()` 仅对 `entry.options.config` 进行插值;`Entry.disabled` 直接测试 `entry.options.disabled`,不经过插值。YAML 标签在语法上合法,因此加载过程不产生任何诊断信息。
+
+快照框架将任何确定性的 transcript(文本记录)视为有效行为。Header pin 验证了组合后的工具 schema,但文件系统场景共享来自默认组合的 pin,因此未独立证明其所需工具已注册。刷新在任何语义断言拒绝缺失工具之前,就已重写了预期的 stdout 和会话日志。
+
+## 已添加的防护措施
+
+- 文件系统场景启动 `fs.cordis.yml`:一个显式的固定全权限 overlay,配有对应的回放配置和独立的 request-header 类。
+- [`AGENTS.md`](../../AGENTS.md) 与 [Cordis 入门](../cordis-primer.md#loader-configuration)明确说明 `!!js` 仅在插件 `config` 内有效,条件式组合应使用 overlay。
+- `verify-cordis-config` 解析仓库中的 Cordis YAML,拒绝 Loader 入口元数据中的表达式节点(包括 include patch 和插入的入口)。
+- `dsh-acp-snapshot` 在新鲜运行和已提交的会话 fixture 中拒绝结构化的 `UNKNOWN_TOOL` 结果,防止其被提交为预期输出。
+
+## 教训
+
+- 语法上被接受的配置值不一定在该位置被求值;应记录并验证插值边界。
+- 快照刷新是 fixture 的生产过程,不是正确性审查。诸如已注册工具缺失这类语义上不可能的结果,需要独立于预期输出的断言。
+- 权限控制只应描述其实际管辖的能力。组合时的文件系统访问无法安全地跟随运行时的 bash-only 预设。
diff --git a/docs/postmortem/README.i18n.yaml b/docs/postmortem/README.i18n.yaml
new file mode 100644
index 0000000000..e68d3a1a07
--- /dev/null
+++ b/docs/postmortem/README.i18n.yaml
@@ -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: df0e2fcb8540aeed005153dbecc451d781ca5ff1
+README.zh.md: 2ce6de475c705b02cd9dabfb2181929d81478e2c
diff --git a/docs/postmortem/README.md b/docs/postmortem/README.md
index 7114f65916..df0e2fcb85 100644
--- a/docs/postmortem/README.md
+++ b/docs/postmortem/README.md
@@ -1,5 +1,7 @@
# Post-mortems
+English | [中文](README.zh.md)
+
Incident write-ups: a bug reached a place it shouldn't have (a real user, a merged PR, a release), and the interesting part is *why our process let it through*, not just the one-line fix.
A post-mortem is NOT an [Agent Note](../../.agents/notes/README.md) (which records a deliberate design decision and its rejected alternatives, or proposes future work). It is a backward-looking record of a failure: what broke, the mechanism, why every safety net missed it, and the concrete guardrails added so the same class of bug fails loudly next time.
diff --git a/docs/postmortem/README.zh.md b/docs/postmortem/README.zh.md
new file mode 100644
index 0000000000..2ce6de475c
--- /dev/null
+++ b/docs/postmortem/README.zh.md
@@ -0,0 +1,16 @@
+# 事故复盘(postmortem)
+
+[English](README.md) | 中文
+
+事故复盘:一个 bug 到达了它不该到达的地方(真实用户、已合并的 PR(Pull Request)、已发布的版本),值得关注的是*为什么我们的流程放过了它*,而不仅仅是那一行修复。
+
+事故复盘不是 [Agent Note(agent 决策记录)](../../.agents/notes/README.md)(Agent Note 记录一个经过深思熟虑的设计决策及其被否决的替代方案,或提出未来工作)。它是一份回顾性的失败记录:什么坏了、机制是什么、为什么每道安全网都没拦住、以及加了哪些具体的防护措施使同类 bug 下次能被显式暴露。
+
+当一个 bug 满足以下条件时,请撰写事故复盘:**隐蔽**(机制不显而易见,即使是细心的工程师也得费力重新推导)、**系统性**(逃逸的原因是测试/工具/约定的缺口,而非一次性的笔误)、**重新发现的代价高**(它消耗了真实的调试时间,且下次还会如此)。请链接该事故复盘所推动建立的防护措施(测试、AGENTS.md 规则、ADR)。
+
+每篇事故复盘以一段**摘要**开头:一个简短段落,让忙碌的读者在三十秒内吸收要点——什么坏了、用直白的话说根因是什么、为什么逃逸了、持久的教训是什么——然后才是后续的详细「概述 / 时间线 / 根因 / 防护措施」各节。
+
+| # | 标题 |
+|---|---|
+| [0001](0001-acp-default-export-drops-inject.md) | ACP(Agent Client Protocol)服务器在连接时崩溃:`export default` 丢失了插件的 `inject` |
+| [0002](0002-js-expression-disabled-filesystem-tools.md) | 文件系统快照工具被一个字面量 `!!js` 对象永久禁用 |
diff --git a/scripts/project-doc-site.spec.ts b/scripts/project-doc-site.spec.ts
index b9872432a5..e6cc11ae6e 100644
--- a/scripts/project-doc-site.spec.ts
+++ b/scripts/project-doc-site.spec.ts
@@ -178,7 +178,7 @@ describe('docsPages locale routes', () => {
const counterpart = byRoute.get(`en/${page.route}`)
expect(counterpart, page.route).toBeDefined()
expect(counterpart?.locale).toBe('en')
- if (page.source.startsWith('docs/user/') || page.route === 'reference/cordis-primer.md') {
+ if (page.contentLocale === 'zh-CN') {
expect(page.source).toMatch(/\.zh\.md$/)
expect(page.contentLocale).toBe('zh-CN')
expect(counterpart?.source).toBe(page.source.replace(/\.zh\.md$/, '.md'))
@@ -190,6 +190,22 @@ describe('docsPages locale routes', () => {
}
})
+ it('projects translated core-data pages while retaining explicit English fallbacks', () => {
+ const rootPages = docsPages.filter(page => (
+ page.locale === 'root' && page.route.startsWith('reference/core-data-structures/')
+ ))
+ const translated = rootPages.filter(page => page.contentLocale === 'zh-CN')
+ const fallbacks = rootPages.filter(page => page.contentLocale === 'en-US')
+
+ expect(translated).toHaveLength(18)
+ expect(translated.every(page => page.source.endsWith('.zh.md'))).toBe(true)
+ expect(fallbacks.map(page => page.source).sort()).toEqual([
+ 'docs/core-data-structures/commands.md',
+ 'docs/core-data-structures/goal.md',
+ 'docs/core-data-structures/pty.md',
+ ])
+ })
+
it('publishes the Cordis core API under matching locale structures', () => {
const files = ['context.md', 'events.md', 'fiber.md', 'registry.md', 'service.md']
for (const file of files) {
diff --git a/scripts/translation-pairing.manifest.json b/scripts/translation-pairing.manifest.json
index ee70bab984..a6503ce282 100644
--- a/scripts/translation-pairing.manifest.json
+++ b/scripts/translation-pairing.manifest.json
@@ -1,14 +1,164 @@
{
"requiredSince": "2026-07-14",
"required": [
+ ".agents/notes/README.md",
+ ".agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.md",
+ ".agents/notes/implemented/architecture/2026-06-11-custom-schema-dsl.md",
+ ".agents/notes/implemented/architecture/2026-06-11-dev-invariants-over-deep-readonly.md",
+ ".agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.md",
+ ".agents/notes/implemented/architecture/2026-06-11-microkernel-event-taxonomy.md",
+ ".agents/notes/implemented/architecture/2026-06-11-runtime-arg-validation.md",
+ ".agents/notes/implemented/architecture/2026-06-11-structured-error-taxonomy.md",
+ ".agents/notes/implemented/architecture/2026-06-11-tool-schemas-in-prompt-assembly.md",
+ ".agents/notes/implemented/architecture/2026-06-13-capability-seams.md",
+ ".agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.md",
+ ".agents/notes/implemented/architecture/2026-06-14-session-persistence.md",
+ ".agents/notes/implemented/architecture/2026-06-15-turn-enclosure-invariant.md",
+ ".agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.md",
+ ".agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-seams.md",
+ ".agents/notes/implemented/architecture/2026-06-18-session-surface.md",
+ ".agents/notes/implemented/architecture/2026-06-18-shared-persistence-write-coordinator.md",
+ ".agents/notes/implemented/architecture/2026-06-20-branded-ids.md",
+ ".agents/notes/implemented/architecture/2026-06-20-extract-example-app-packages.md",
+ ".agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md",
+ ".agents/notes/implemented/architecture/2026-06-20-package-hierarchy.md",
+ ".agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.md",
+ ".agents/notes/implemented/architecture/2026-06-24-web-capability-seam.md",
+ ".agents/notes/implemented/architecture/2026-06-26-file-context-as-event-gate.md",
+ ".agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-surface.md",
+ ".agents/notes/implemented/architecture/2026-06-30-event-domain-semantics.md",
+ ".agents/notes/implemented/architecture/2026-07-02-fs-per-session-cwd.md",
+ ".agents/notes/implemented/architecture/2026-07-02-result-time-applied-hunk-diffs.md",
+ ".agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.md",
+ ".agents/notes/implemented/architecture/2026-07-03-filesystem-directory-listing-seam.md",
+ ".agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.md",
+ ".agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.md",
+ ".agents/notes/implemented/architecture/2026-07-05-subagent-provider-lifecycle-events.md",
+ ".agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.md",
+ ".agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.md",
+ ".agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.md",
".agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md",
+ ".agents/notes/implemented/architecture/2026-07-12-agent-scope-runtime-design.md",
".agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.md",
".agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.md",
".agents/notes/implemented/architecture/2026-07-19-gui-web-client-architecture.md",
".agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.md",
".agents/notes/implemented/architecture/2026-07-23-client-plugin-loading-model.md",
+ ".agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.md",
+ ".agents/notes/implemented/feature/2026-06-14-acp-multi-session.md",
+ ".agents/notes/implemented/feature/2026-06-15-code-mode.md",
+ ".agents/notes/implemented/feature/2026-06-17-filesystem-tool-schemas.md",
+ ".agents/notes/implemented/feature/2026-06-18-acp-terminal-and-tool-rendering.md",
+ ".agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.md",
+ ".agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.md",
+ ".agents/notes/implemented/feature/2026-06-22-acp-subagent-backend.md",
+ ".agents/notes/implemented/feature/2026-06-25-ask-user-question.md",
+ ".agents/notes/implemented/feature/2026-06-29-todo-write-tool.md",
+ ".agents/notes/implemented/feature/2026-06-30-hook-bridges.md",
+ ".agents/notes/implemented/feature/2026-06-30-hook-protocol-lib.md",
+ ".agents/notes/implemented/feature/2026-06-30-interception-seams.md",
+ ".agents/notes/implemented/feature/2026-06-30-session-store-fork-api.md",
+ ".agents/notes/implemented/feature/2026-06-30-subagent-observe-enrich.md",
+ ".agents/notes/implemented/feature/2026-07-05-dynamic-workflows.md",
+ ".agents/notes/implemented/feature/2026-07-05-skill-system.md",
+ ".agents/notes/implemented/feature/2026-07-06-approval-seam.md",
+ ".agents/notes/implemented/feature/2026-07-06-explicit-tool-order.md",
+ ".agents/notes/implemented/feature/2026-07-06-sandbox.md",
+ ".agents/notes/implemented/feature/2026-07-07-mcp-client-plugin.md",
+ ".agents/notes/implemented/feature/2026-07-07-session-prefix.md",
+ ".agents/notes/implemented/feature/2026-07-08-repeat-tool-guard.md",
+ ".agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md",
+ ".agents/notes/implemented/feature/2026-07-10-session-query-service.md",
+ ".agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md",
+ ".agents/notes/implemented/process/2026-06-11-doc-sync-enforcement.md",
+ ".agents/notes/implemented/process/2026-06-11-quality-gates.md",
+ ".agents/notes/implemented/process/2026-06-11-tsdown-over-dumble.md",
+ ".agents/notes/implemented/process/2026-06-11-vendor-cordis-as-source.md",
+ ".agents/notes/implemented/process/2026-06-16-pnpm-over-yarn.md",
+ ".agents/notes/implemented/process/2026-06-17-ts-build-config.md",
+ ".agents/notes/implemented/process/2026-06-18-markdown-cross-link-lint.md",
+ ".agents/notes/implemented/process/2026-06-20-agent-note-classification.md",
+ ".agents/notes/implemented/process/2026-06-20-core-data-structures-catalog.md",
+ ".agents/notes/implemented/process/2026-06-20-generated-cordis-catalog.md",
".agents/notes/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.md",
+ ".agents/notes/implemented/process/2026-07-02-tool-schema-catalog.md",
+ ".agents/notes/implemented/process/2026-07-03-documentation-graph-atlas.md",
+ ".agents/notes/implemented/process/2026-07-04-cordis-jsdoc-completeness-gate.md",
+ ".agents/notes/implemented/process/2026-07-04-doc-tiers-and-budgets.md",
+ ".agents/notes/implemented/process/2026-07-04-persistence-log-catalog.md",
+ ".agents/notes/implemented/process/2026-07-05-uniform-agent-note-format.md",
+ ".agents/notes/implemented/process/2026-07-06-export-surface-jsdoc-gate.md",
+ ".agents/notes/implemented/process/2026-07-06-generated-config-catalog.md",
+ ".agents/notes/implemented/process/2026-07-06-node-engine-floor.md",
+ ".agents/notes/implemented/process/2026-07-06-parallel-github-ci-gates.md",
+ ".agents/notes/implemented/process/2026-07-06-parallel-pre-push-gates.md",
+ ".agents/notes/implemented/process/2026-07-10-readme-known-limitations-gate.md",
+ ".agents/notes/implemented/process/2026-07-12-package-model-experience-contract.md",
".agents/notes/implemented/process/2026-07-19-web-styling-system.md",
+ ".agents/notes/implemented/simplification/2026-06-19-drop-mutable-session-summary.md",
+ ".agents/notes/implemented/simplification/2026-06-20-collapse-trace-only-session-events.md",
+ ".agents/notes/implemented/simplification/2026-06-20-drop-unconsumed-llm-adapter-change-event.md",
+ ".agents/notes/implemented/simplification/2026-06-20-drop-unconsumed-llm-assembled-surfaces.md",
+ ".agents/notes/implemented/simplification/2026-06-20-prune-dead-seam-methods.md",
+ ".agents/notes/implemented/simplification/2026-06-20-public-agent-stop-surface.md",
+ ".agents/notes/implemented/simplification/2026-06-20-remove-agent-boundary-mirror-events.md",
+ ".agents/notes/implemented/simplification/2026-06-20-unify-agent-and-session-id.md",
+ ".agents/notes/implemented/simplification/2026-06-26-fsspec-style-fs-seam.md",
+ ".agents/notes/implemented/simplification/2026-07-02-remove-stream-chunk-mirror.md",
+ ".agents/notes/implemented/simplification/2026-07-04-drop-image-content-block.md",
+ ".agents/notes/implemented/simplification/2026-07-04-drop-inert-request-knobs.md",
+ ".agents/notes/implemented/simplification/2026-07-04-drop-unconsumed-web-observation-surface.md",
+ ".agents/notes/implemented/simplification/2026-07-04-fold-stdio-ui-helper.md",
+ ".agents/notes/implemented/simplification/2026-07-04-prune-producerless-vocabulary-variants.md",
+ ".agents/notes/implemented/simplification/2026-07-04-prune-write-only-fs-surface.md",
+ ".agents/notes/implemented/simplification/2026-07-04-remove-agent-steering-mirror.md",
+ ".agents/notes/implemented/simplification/2026-07-04-share-app-bin-boot-glue.md",
+ ".agents/notes/implemented/simplification/2026-07-04-tighten-hook-protocol-contract.md",
+ ".agents/notes/implemented/simplification/2026-07-04-trim-acp-bridge-unreachable-surface.md",
+ ".agents/notes/implemented/simplification/2026-07-12-drop-unconsumed-skill-provider-events.md",
+ ".agents/notes/implemented/simplification/2026-07-12-prune-unused-web-seam-fields.md",
+ ".agents/notes/implemented/simplification/2026-07-12-simplify-session-log-representation.md",
+ ".agents/notes/implemented/testing/2026-06-11-property-based-testing.md",
+ ".agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.md",
+ ".agents/notes/implemented/testing/2026-06-19-real-api-e2e-ci.md",
+ ".agents/notes/implemented/testing/2026-06-20-remove-redundant-snapshot-log-expected-output.md",
+ ".agents/notes/implemented/testing/2026-06-22-fork-child-replay-seed-boundary.md",
+ ".agents/notes/implemented/testing/2026-06-22-fork-snapshot-scenarios.md",
+ ".agents/notes/implemented/testing/2026-06-22-subagent-snapshot-replay.md",
+ ".agents/notes/implemented/testing/2026-07-04-hook-snapshot-matrix.md",
+ ".agents/notes/implemented/testing/2026-07-04-single-source-acp-replay-config.md",
+ ".agents/notes/implemented/testing/2026-07-06-pin-request-header-content-in-one-scenario.md",
+ ".agents/notes/implemented/testing/2026-07-08-shared-acp-snapshot-package.md",
+ ".agents/notes/proposed/architecture/2026-06-16-typed-event-schemas.md",
+ ".agents/notes/proposed/feature/2026-06-30-pre-tool-input-rewrite.md",
+ ".agents/notes/proposed/feature/2026-07-07-claude-code-and-codex-subagent-backends.md",
+ ".agents/notes/proposed/feature/2026-07-08-interactive-side-sessions.md",
+ ".agents/notes/implemented/feature/2026-07-10-sqlite-session-query-provider.md",
+ ".agents/notes/proposed/feature/2026-07-13-stream-workflow-progress-through-tool-calls.md",
+ ".agents/notes/proposed/process/2026-06-11-api-extractor-reports.md",
+ ".agents/notes/proposed/process/2026-06-11-architectural-conformance.md",
+ ".agents/notes/proposed/process/2026-06-11-supply-chain-and-vendor-drift.md",
+ ".agents/notes/proposed/process/2026-06-20-discover-package-inventory.md",
+ ".agents/notes/proposed/simplification/2026-07-04-prune-dead-core-spine-surface.md",
+ ".agents/notes/proposed/testing/2026-06-11-deterministic-and-stress-testing.md",
+ ".agents/notes/proposed/testing/2026-06-11-mutation-testing.md",
+ ".agents/notes/rejected/architecture/2026-06-11-immutable-public-surfaces.md",
+ ".agents/notes/rejected/architecture/2026-06-20-providerless-example-base.md",
+ ".agents/notes/rejected/process/2026-07-04-generate-agent-note-index-tables.md",
+ ".agents/notes/rejected/simplification/2026-06-20-assembled-assistant-messages-only.md",
+ ".agents/notes/rejected/simplification/2026-06-20-drop-acp-session-load.md",
+ ".agents/notes/rejected/simplification/2026-06-20-drop-acp-terminal-meta.md",
+ ".agents/notes/rejected/simplification/2026-06-20-drop-bash-output-spill-files.md",
+ ".agents/notes/rejected/simplification/2026-06-20-drop-durable-step-boundaries.md",
+ ".agents/notes/rejected/simplification/2026-06-20-drop-unused-session-lineage.md",
+ ".agents/notes/rejected/simplification/2026-06-20-fold-session-persistence-interface.md",
+ ".agents/notes/rejected/simplification/2026-06-20-generic-tool-rendering.md",
+ ".agents/notes/rejected/simplification/2026-06-20-retire-mid-turn-steering.md",
+ ".agents/notes/rejected/simplification/2026-06-20-single-session-acp-bridge.md",
+ ".agents/notes/rejected/simplification/2026-06-20-truncate-interrupted-turns.md",
+ ".agents/notes/rejected/simplification/2026-07-04-prune-unimplemented-subagent-vocabulary.md",
+ ".agents/notes/rejected/simplification/2026-07-12-collapse-workflow-to-foreground-core.md",
+ ".agents/notes/rejected/simplification/2026-07-12-prune-unused-skill-registry-surface.md",
"README.md",
"docs/architecture.md",
"docs/cookbook/adding-a-package.md",
@@ -18,11 +168,33 @@
"docs/cookbook/extension-cookbook.md",
"docs/cookbook/responding-to-pr-review-on-a-stack.md",
"docs/cordis-primer.md",
+ "docs/core-data-structures/approval.md",
+ "docs/core-data-structures/bash.md",
+ "docs/core-data-structures/code-runtime.md",
+ "docs/core-data-structures/compaction.md",
+ "docs/core-data-structures/core.md",
+ "docs/core-data-structures/filesystem.md",
+ "docs/core-data-structures/llm-streaming.md",
+ "docs/core-data-structures/persistence.md",
+ "docs/core-data-structures/sandbox.md",
+ "docs/core-data-structures/scope.md",
+ "docs/core-data-structures/session-query.md",
+ "docs/core-data-structures/session.md",
+ "docs/core-data-structures/skills.md",
+ "docs/core-data-structures/subagent.md",
+ "docs/core-data-structures/system-prompt.md",
+ "docs/core-data-structures/tools.md",
+ "docs/core-data-structures/user-interaction.md",
+ "docs/core-data-structures/web.md",
+ "docs/core-data-structures/workflow.md",
"docs/defensive-patterns.md",
"docs/development.md",
"docs/glossary.md",
"docs/i18n/README.md",
"docs/i18n/translation-rules.md",
+ "docs/postmortem/0001-acp-default-export-drops-inject.md",
+ "docs/postmortem/0002-js-expression-disabled-filesystem-tools.md",
+ "docs/postmortem/README.md",
"docs/testing.md",
"docs/user/develop/basic/config.md",
"docs/user/develop/basic/index.md",
diff --git a/scripts/type-equiv.manifest.json b/scripts/type-equiv.manifest.json
index db5fc0b85d..a15fc21a96 100644
--- a/scripts/type-equiv.manifest.json
+++ b/scripts/type-equiv.manifest.json
@@ -439,26 +439,6 @@
"symbol": "SessionEventTrace",
"source": "packages/session-query/session-query/src/types.ts"
},
- {
- "doc": "docs/core-data-structures/session-reference.md",
- "symbol": "SessionReferenceInput",
- "source": "packages/context/session-reference/src/types.ts"
- },
- {
- "doc": "docs/core-data-structures/session-reference.md",
- "symbol": "SessionReferenceCandidate",
- "source": "packages/context/session-reference/src/types.ts"
- },
- {
- "doc": "docs/core-data-structures/session-reference.md",
- "symbol": "PreparedReferencedMessage",
- "source": "packages/context/session-reference/src/types.ts"
- },
- {
- "doc": "docs/core-data-structures/session-reference.md",
- "symbol": "SessionReferenceErrorCode",
- "source": "packages/context/session-reference/src/config.ts"
- },
{
"doc": "docs/core-data-structures/session-title.md",
"symbol": "SessionTitleProviderId",
@@ -514,6 +494,26 @@
"symbol": "SessionTitleProvider",
"source": "packages/session-title/session-title/src/index.ts"
},
+ {
+ "doc": "docs/core-data-structures/session-reference.md",
+ "symbol": "SessionReferenceInput",
+ "source": "packages/context/session-reference/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-reference.md",
+ "symbol": "SessionReferenceCandidate",
+ "source": "packages/context/session-reference/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-reference.md",
+ "symbol": "PreparedReferencedMessage",
+ "source": "packages/context/session-reference/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-reference.md",
+ "symbol": "SessionReferenceErrorCode",
+ "source": "packages/context/session-reference/src/config.ts"
+ },
{
"doc": "docs/core-data-structures/tools.md",
"symbol": "ToolOutputDefinition",
@@ -1208,6 +1208,909 @@
"doc": "docs/core-data-structures/session-query.md",
"symbol": "SessionSearchHit",
"source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "Branded",
+ "source": "packages/util/brand/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "ContentBlockMap",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "AssistantProvenance",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "Message",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "MessageSourceMap",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "FinishReasonMap",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "LlmProviderInfo",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "LlmModelInfo",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "LlmModelContext",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "GenerateOptions",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "ToolSchema",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "LlmCallConfig",
+ "source": "packages/llm/llm/src/call-config.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "SessionEvent",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "SendOptions",
+ "source": "packages/core/agent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "AgentCancelCause",
+ "source": "packages/core/agent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "InjectOptions",
+ "source": "packages/core/agent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "Agent",
+ "source": "packages/core/agent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "HookContext",
+ "source": "packages/core/agent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "PromptDecision",
+ "source": "packages/core/agent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "ContinuationDecision",
+ "source": "packages/core/agent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "RequestError",
+ "source": "packages/core/agent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "RequestErrorDecision",
+ "source": "packages/core/agent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "ContinuationStop",
+ "source": "packages/core/agent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/core.zh.md",
+ "symbol": "SessionStartSource",
+ "source": "packages/core/agent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/scope.zh.md",
+ "symbol": "ScopeKey",
+ "source": "packages/core/scope/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/scope.zh.md",
+ "symbol": "Scoped",
+ "source": "packages/core/scope/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/scope.zh.md",
+ "symbol": "Scope",
+ "source": "packages/core/scope/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/scope.zh.md",
+ "symbol": "ScopeLayer",
+ "source": "packages/core/scope/src/store.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/system-prompt.zh.md",
+ "symbol": "AssembleContext",
+ "source": "packages/core/system-prompt/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/system-prompt.zh.md",
+ "symbol": "PromptSection",
+ "source": "packages/core/system-prompt/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/system-prompt.zh.md",
+ "symbol": "ToolProviderResult",
+ "source": "packages/core/system-prompt/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/llm-streaming.zh.md",
+ "symbol": "StreamChunk",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/llm-streaming.zh.md",
+ "symbol": "LlmFailure",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/llm-streaming.zh.md",
+ "symbol": "TokenUsage",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/llm-streaming.zh.md",
+ "symbol": "ContentBlockMap",
+ "source": "packages/llm/llm/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/llm-streaming.zh.md",
+ "symbol": "AppIdentity",
+ "source": "packages/llm/llm/src/attribution.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/llm-streaming.zh.md",
+ "symbol": "BlockAssembler",
+ "source": "packages/llm/llm/src/assembler.ts",
+ "projection": "public-api"
+ },
+ {
+ "doc": "docs/core-data-structures/llm-streaming.zh.md",
+ "symbol": "LlmAdapter",
+ "source": "packages/llm/llm/src/index.ts",
+ "projection": "public-api"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "PromptMessageData",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "SessionEventMap",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "OutOfBandSessionEventMap",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "EpochHeader",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "TodoItem",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "SessionEvent",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "TurnTriggerMap",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "TurnEndReasonMap",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "SurfaceEventType",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "SurfaceOp",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "SurfaceIntent",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "SessionSurface",
+ "source": "packages/core/session/src/surface.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "SurfaceFoldReplacement",
+ "source": "packages/core/session/src/surface.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "SurfaceFoldResult",
+ "source": "packages/core/session/src/surface.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session.zh.md",
+ "symbol": "Session",
+ "source": "packages/core/session/src/index.ts",
+ "projection": "public-api"
+ },
+ {
+ "doc": "docs/core-data-structures/persistence.zh.md",
+ "symbol": "SessionHeader",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/persistence.zh.md",
+ "symbol": "CreateSessionOptions",
+ "source": "packages/core/session/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/persistence.zh.md",
+ "symbol": "SessionLocation",
+ "source": "packages/session-persistence/session-persistence/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/persistence.zh.md",
+ "symbol": "SessionPersistenceRevision",
+ "source": "packages/session-persistence/session-persistence/src/revision.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/persistence.zh.md",
+ "symbol": "SessionPersistenceSnapshot",
+ "source": "packages/session-persistence/session-persistence/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionEventSurface",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionRecord",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionLogSnapshot",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionSurfaceSnapshot",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionEventRecord",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionResultFilter",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionEventResultFilter",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionEventSearchDocument",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionSearchCursor",
+ "source": "packages/session-query/session-query/src/cursor.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionSearchRequest",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionEventSearchRequest",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionSearchPage",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionEventSearchHit",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionSearchHit",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionLineageNode",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionLineageTrace",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionQueryErrorCode",
+ "source": "packages/session-query/session-query/src/config.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionEventReadRequest",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionEventWindow",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionEventTraceRequest",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/session-query.zh.md",
+ "symbol": "SessionEventTrace",
+ "source": "packages/session-query/session-query/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolOutputDefinition",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolDefinition",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ValueSchemaSpec",
+ "source": "packages/core/tools/src/schema.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ParameterPropertySpec",
+ "source": "packages/core/tools/src/schema.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ParameterSchemaSpec",
+ "source": "packages/core/tools/src/schema.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "InferValue",
+ "source": "packages/core/tools/src/schema.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "InferArgs",
+ "source": "packages/core/tools/src/schema.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolExecutionToken",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolExecutionInput",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolExecution",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolDispatchExecution",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolExecutionMode",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolRunContext",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolGuard",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolRestriction",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolFailure",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolExecutionSuccess",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolExecutionFailure",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ToolExecutionResult",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "PreToolDecision",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "PostToolDecision",
+ "source": "packages/core/tools/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "JsonSchemaScalar",
+ "source": "packages/core/tools/src/json-schema.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "JsonSchemaType",
+ "source": "packages/core/tools/src/json-schema.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "JsonSchemaNode",
+ "source": "packages/core/tools/src/json-schema.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/tools.zh.md",
+ "symbol": "ObjectJsonSchema",
+ "source": "packages/core/tools/src/json-schema.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/user-interaction.zh.md",
+ "symbol": "AskUserQuestionOption",
+ "source": "packages/ui/user-interaction/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/user-interaction.zh.md",
+ "symbol": "AskUserQuestionItem",
+ "source": "packages/ui/user-interaction/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/user-interaction.zh.md",
+ "symbol": "AskUserQuestionRequest",
+ "source": "packages/ui/user-interaction/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/user-interaction.zh.md",
+ "symbol": "AskUserQuestionAnswerItem",
+ "source": "packages/ui/user-interaction/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/user-interaction.zh.md",
+ "symbol": "AskUserQuestionAnswer",
+ "source": "packages/ui/user-interaction/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/user-interaction.zh.md",
+ "symbol": "UserInteractionProvider",
+ "source": "packages/ui/user-interaction/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/user-interaction.zh.md",
+ "symbol": "UserInteractionError",
+ "source": "packages/ui/user-interaction/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/approval.zh.md",
+ "symbol": "ApprovalRequestId",
+ "source": "packages/ui/user-approval/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/approval.zh.md",
+ "symbol": "ApprovalOutcome",
+ "source": "packages/ui/user-approval/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/approval.zh.md",
+ "symbol": "ApprovalPolicy",
+ "source": "packages/ui/user-approval/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/approval.zh.md",
+ "symbol": "ApprovalRequest",
+ "source": "packages/ui/user-approval/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/bash.zh.md",
+ "symbol": "DshEnvironmentKey",
+ "source": "packages/bash/bash/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/bash.zh.md",
+ "symbol": "DshEnvironment",
+ "source": "packages/bash/bash/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/bash.zh.md",
+ "symbol": "BashExecRequest",
+ "source": "packages/bash/bash/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/bash.zh.md",
+ "symbol": "BashExecSpec",
+ "source": "packages/bash/bash/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/bash.zh.md",
+ "symbol": "BashRunResult",
+ "source": "packages/bash/bash/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/bash.zh.md",
+ "symbol": "BashSandboxInfo",
+ "source": "packages/bash/bash/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/bash.zh.md",
+ "symbol": "CollectedOutput",
+ "source": "packages/bash/bash/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/bash.zh.md",
+ "symbol": "BashProcess",
+ "source": "packages/bash/bash/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/bash.zh.md",
+ "symbol": "BashProcessRead",
+ "source": "packages/bash/bash/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/sandbox.zh.md",
+ "symbol": "SandboxMode",
+ "source": "packages/sandbox/sandbox/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/sandbox.zh.md",
+ "symbol": "ConfinedSandboxMode",
+ "source": "packages/sandbox/sandbox/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/sandbox.zh.md",
+ "symbol": "SandboxExecutionPolicy",
+ "source": "packages/sandbox/sandbox/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/sandbox.zh.md",
+ "symbol": "SandboxEnforcement",
+ "source": "packages/sandbox/sandbox/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/sandbox.zh.md",
+ "symbol": "SandboxPolicy",
+ "source": "packages/sandbox/sandbox/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/sandbox.zh.md",
+ "symbol": "SandboxPolicyRequest",
+ "source": "packages/sandbox/sandbox-policy/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/sandbox.zh.md",
+ "symbol": "ConfinedArgv",
+ "source": "packages/sandbox/sandbox/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/code-runtime.zh.md",
+ "symbol": "CodeJsonValue",
+ "source": "packages/code-runtime/code-runtime/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/code-runtime.zh.md",
+ "symbol": "CodeRunRequest",
+ "source": "packages/code-runtime/code-runtime/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/code-runtime.zh.md",
+ "symbol": "CodeRunResult",
+ "source": "packages/code-runtime/code-runtime/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/code-runtime.zh.md",
+ "symbol": "CodeBindingNamespace",
+ "source": "packages/code-runtime/code-runtime/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/code-runtime.zh.md",
+ "symbol": "CodeBindingErrorClass",
+ "source": "packages/code-runtime/code-runtime/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/code-runtime.zh.md",
+ "symbol": "CodeBindingFunction",
+ "source": "packages/code-runtime/code-runtime/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/code-runtime.zh.md",
+ "symbol": "CodeRunFailure",
+ "source": "packages/code-runtime/code-runtime/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsTarget",
+ "source": "packages/fs/fs/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsTargetKey",
+ "source": "packages/fs/fs/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsVersion",
+ "source": "packages/fs/fs/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsInfo",
+ "source": "packages/fs/fs/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsPathInfo",
+ "source": "packages/fs/fs/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsDirEntry",
+ "source": "packages/fs/fs/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsWriteIntent",
+ "source": "packages/fs/fs/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsWriteOutcome",
+ "source": "packages/fs/fs/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsEditRequest",
+ "source": "packages/fs/fs/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsEditOutcome",
+ "source": "packages/fs/fs/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsErrorCode",
+ "source": "packages/fs/fs/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FsPolicyExec",
+ "source": "packages/fs/fs-policy/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/filesystem.zh.md",
+ "symbol": "FileReadOutcome",
+ "source": "packages/fs/tool-fs/src/read-render.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/skills.zh.md",
+ "symbol": "SkillSource",
+ "source": "packages/skill/skill/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/skills.zh.md",
+ "symbol": "SkillResourceBase",
+ "source": "packages/skill/skill/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/skills.zh.md",
+ "symbol": "SkillSummary",
+ "source": "packages/skill/skill/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/skills.zh.md",
+ "symbol": "SkillCandidate",
+ "source": "packages/skill/skill/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/skills.zh.md",
+ "symbol": "SkillDefinition",
+ "source": "packages/skill/skill/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/skills.zh.md",
+ "symbol": "SkillRegistration",
+ "source": "packages/skill/skill/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/skills.zh.md",
+ "symbol": "SkillLookupOptions",
+ "source": "packages/skill/skill/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/skills.zh.md",
+ "symbol": "SkillProvider",
+ "source": "packages/skill/skill/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/skills.zh.md",
+ "symbol": "Config",
+ "source": "packages/skill/skill/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/compaction.zh.md",
+ "symbol": "CompactionResult",
+ "source": "packages/compact/compact/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/compaction.zh.md",
+ "symbol": "CompactionTrigger",
+ "source": "packages/compact/compact/src/index.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/compaction.zh.md",
+ "symbol": "PrunedEntry",
+ "source": "packages/compact/compact-tool-result-prune/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/compaction.zh.md",
+ "symbol": "PruneResult",
+ "source": "packages/compact/compact-tool-result-prune/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/subagent.zh.md",
+ "symbol": "SubagentCapabilities",
+ "source": "packages/subagent/subagent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/subagent.zh.md",
+ "symbol": "SubagentStartRequest",
+ "source": "packages/subagent/subagent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/subagent.zh.md",
+ "symbol": "SubagentResult",
+ "source": "packages/subagent/subagent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/subagent.zh.md",
+ "symbol": "SubagentStopReasonMap",
+ "source": "packages/subagent/subagent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/subagent.zh.md",
+ "symbol": "SubagentRun",
+ "source": "packages/subagent/subagent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/subagent.zh.md",
+ "symbol": "SubagentProvider",
+ "source": "packages/subagent/subagent/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/web.zh.md",
+ "symbol": "WebSearchRequest",
+ "source": "packages/web/web/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/web.zh.md",
+ "symbol": "WebSearchResult",
+ "source": "packages/web/web/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/web.zh.md",
+ "symbol": "WebSearchSource",
+ "source": "packages/web/web/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/web.zh.md",
+ "symbol": "WebFetchRequest",
+ "source": "packages/web/web/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/web.zh.md",
+ "symbol": "WebFetchResult",
+ "source": "packages/web/web/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/web.zh.md",
+ "symbol": "WebFetchBody",
+ "source": "packages/web/web/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/workflow.zh.md",
+ "symbol": "WorkflowStartRequest",
+ "source": "packages/workflow/workflow/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/workflow.zh.md",
+ "symbol": "WorkflowMeta",
+ "source": "packages/workflow/workflow/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/workflow.zh.md",
+ "symbol": "WorkflowResult",
+ "source": "packages/workflow/workflow/src/types.ts"
+ },
+ {
+ "doc": "docs/core-data-structures/workflow.zh.md",
+ "symbol": "WorkflowRun",
+ "source": "packages/workflow/workflow/src/types.ts"
}
]
}
diff --git a/website/docs.ts b/website/docs.ts
index e033e2d6ef..1888cd908c 100644
--- a/website/docs.ts
+++ b/website/docs.ts
@@ -237,6 +237,35 @@ const cordisPrimerReference = pairedPages([
},
])
+const coreDataReference = pairedPages(([
+ ['core.md', '核心数据结构', 'Core data structures', 0],
+ ['scope.md', '作用域', 'Scopes', 1],
+ ['session.md', '会话', 'Sessions', 2],
+ ['system-prompt.md', '系统提示词', 'System prompts', 4],
+ ['tools.md', '工具', 'Tools', 5],
+ ['llm-streaming.md', 'LLM 流式响应', 'LLM streaming', 6],
+ ['bash.md', 'Bash 执行', 'Bash execution', 7],
+ ['filesystem.md', '文件系统', 'Filesystem', 9],
+ ['code-runtime.md', '代码运行时', 'Code runtime', 10],
+ ['compaction.md', '上下文压缩', 'Compaction', 11],
+ ['subagent.md', '子代理', 'Subagents', 12],
+ ['workflow.md', '工作流', 'Workflows', 13],
+ ['skills.md', '技能', 'Skills', 14],
+ ['approval.md', '审批', 'Approvals', 15],
+ ['user-interaction.md', '用户交互', 'User interaction', 16],
+ ['sandbox.md', '沙箱', 'Sandboxing', 18],
+ ['web.md', 'Web 访问', 'Web access', 19],
+ ['persistence.md', '会话持久化', 'Session persistence', 20],
+] as const).map(([file, rootLabel, enLabel, order]): PairedPage => ({
+ source: `docs/core-data-structures/${file}`,
+ route: `reference/core-data-structures/${file}`,
+ label: { root: rootLabel, en: enLabel },
+ sidebar: { root: 'zh-reference', en: 'en-reference' },
+ section: { root: '数据结构', en: 'Data structures' },
+ order,
+ ...(file === 'core.md' ? { sourceAliases: ['docs/core-data-structures'] } : {}),
+})))
+
const reference = mirroredPages([
...([
['docs/architecture.md', 'reference/index.md', '架构', 'Architecture', 0],
@@ -283,28 +312,10 @@ const reference = mirroredPages([
order,
})),
...([
- ['core.md', '核心数据结构', 'Core data structures'],
- ['scope.md', '作用域', 'Scopes'],
- ['session.md', '会话', 'Sessions'],
- ['goal.md', '目标', 'Goals'],
- ['system-prompt.md', '系统提示词', 'System prompts'],
- ['tools.md', '工具', 'Tools'],
- ['llm-streaming.md', 'LLM 流式响应', 'LLM streaming'],
- ['bash.md', 'Bash 执行', 'Bash execution'],
- ['pty.md', 'PTY 会话', 'PTY sessions'],
- ['filesystem.md', '文件系统', 'Filesystem'],
- ['code-runtime.md', '代码运行时', 'Code runtime'],
- ['compaction.md', '上下文压缩', 'Compaction'],
- ['subagent.md', '子代理', 'Subagents'],
- ['workflow.md', '工作流', 'Workflows'],
- ['skills.md', '技能', 'Skills'],
- ['approval.md', '审批', 'Approvals'],
- ['user-interaction.md', '用户交互', 'User interaction'],
- ['commands.md', '命令', 'Human commands'],
- ['sandbox.md', '沙箱', 'Sandboxing'],
- ['web.md', 'Web 访问', 'Web access'],
- ['persistence.md', '会话持久化', 'Session persistence'],
- ] as const).map(([file, rootLabel, enLabel], order): MirroredPage => ({
+ ['goal.md', '目标', 'Goals', 3],
+ ['pty.md', 'PTY 会话', 'PTY sessions', 8],
+ ['commands.md', '命令', 'Human commands', 17],
+ ] as const).map(([file, rootLabel, enLabel, order]): MirroredPage => ({
source: `docs/core-data-structures/${file}`,
route: `reference/core-data-structures/${file}`,
contentLocale: 'en-US',
@@ -312,7 +323,6 @@ const reference = mirroredPages([
sidebar: { root: 'zh-reference', en: 'en-reference' },
section: { root: '数据结构', en: 'Data structures' },
order,
- ...(file === 'core.md' ? { sourceAliases: ['docs/core-data-structures'] } : {}),
})),
...([
['adding-a-package.md', '新增 Package', 'Adding a package'],
@@ -336,5 +346,6 @@ export const docsPages: DocsPage[] = [
...develop,
...cordisTutorial,
...cordisPrimerReference,
+ ...coreDataReference,
...reference,
]