From 47e3e6f0ed40dfe8f424456899a25ad3e084ab75 Mon Sep 17 00:00:00 2001 From: fz Date: Wed, 12 Aug 2026 21:47:28 +0800 Subject: [PATCH 01/34] feat(web): rename code preset to PTC mode --- apps/cli/config/agent-presets/code/preset.yml | 2 +- .../snapshots/agent-preset-authoring/created.expected.md | 8 ++++---- .../snapshots/agent-preset-authoring/damaged.expected.md | 8 ++++---- .../snapshots/agent-preset-authoring/section.expected.md | 8 ++++---- packages/client/ui-agent-preset/src/client/locales.ts | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/cli/config/agent-presets/code/preset.yml b/apps/cli/config/agent-presets/code/preset.yml index 17eaccb871..fc0836f479 100644 --- a/apps/cli/config/agent-presets/code/preset.yml +++ b/apps/cli/config/agent-presets/code/preset.yml @@ -1,3 +1,3 @@ -name: 代码模式 +name: PTC 模式 description: 具备标准模式的全部能力,并通过 Code Mode SDK 呈现工具,让模型用一个 TypeScript 程序组合多步操作。 order: 2 diff --git a/apps/web/tests/snapshots/agent-preset-authoring/created.expected.md b/apps/web/tests/snapshots/agent-preset-authoring/created.expected.md index 40b9497831..ed674dfd57 100644 --- a/apps/web/tests/snapshots/agent-preset-authoring/created.expected.md +++ b/apps/web/tests/snapshots/agent-preset-authoring/created.expected.md @@ -35,13 +35,13 @@ - img - text: 复制 - listitem: - - 'button "设为默认: 代码模式"': - - text: 代码模式 内置 具备标准模式的全部能力,并通过 Code Mode SDK 呈现工具,让模型用一个 TypeScript 程序组合多步操作。 + - 'button "设为默认: PTC 模式"': + - text: PTC 模式 内置 具备标准模式的全部能力,并通过 Code Mode SDK 呈现工具,让模型用一个 TypeScript 程序组合多步操作。 - code: code - - 'button "查看: 代码模式"': + - 'button "查看: PTC 模式"': - img - text: 查看 - - 'button "复制: 代码模式"': + - 'button "复制: PTC 模式"': - img - text: 复制 - listitem: diff --git a/apps/web/tests/snapshots/agent-preset-authoring/damaged.expected.md b/apps/web/tests/snapshots/agent-preset-authoring/damaged.expected.md index c3e9035098..688fb65822 100644 --- a/apps/web/tests/snapshots/agent-preset-authoring/damaged.expected.md +++ b/apps/web/tests/snapshots/agent-preset-authoring/damaged.expected.md @@ -35,13 +35,13 @@ - img - text: 复制 - listitem: - - 'button "设为默认: 代码模式"': - - text: 代码模式 内置 具备标准模式的全部能力,并通过 Code Mode SDK 呈现工具,让模型用一个 TypeScript 程序组合多步操作。 + - 'button "设为默认: PTC 模式"': + - text: PTC 模式 内置 具备标准模式的全部能力,并通过 Code Mode SDK 呈现工具,让模型用一个 TypeScript 程序组合多步操作。 - code: code - - 'button "查看: 代码模式"': + - 'button "查看: PTC 模式"': - img - text: 查看 - - 'button "复制: 代码模式"': + - 'button "复制: PTC 模式"': - img - text: 复制 - listitem: diff --git a/apps/web/tests/snapshots/agent-preset-authoring/section.expected.md b/apps/web/tests/snapshots/agent-preset-authoring/section.expected.md index e411e8ea28..b4bd5f44e6 100644 --- a/apps/web/tests/snapshots/agent-preset-authoring/section.expected.md +++ b/apps/web/tests/snapshots/agent-preset-authoring/section.expected.md @@ -35,13 +35,13 @@ - img - text: 复制 - listitem: - - 'button "设为默认: 代码模式"': - - text: 代码模式 内置 具备标准模式的全部能力,并通过 Code Mode SDK 呈现工具,让模型用一个 TypeScript 程序组合多步操作。 + - 'button "设为默认: PTC 模式"': + - text: PTC 模式 内置 具备标准模式的全部能力,并通过 Code Mode SDK 呈现工具,让模型用一个 TypeScript 程序组合多步操作。 - code: code - - 'button "查看: 代码模式"': + - 'button "查看: PTC 模式"': - img - text: 查看 - - 'button "复制: 代码模式"': + - 'button "复制: PTC 模式"': - img - text: 复制 - listitem: diff --git a/packages/client/ui-agent-preset/src/client/locales.ts b/packages/client/ui-agent-preset/src/client/locales.ts index 2a3dee06f3..54acc298a1 100644 --- a/packages/client/ui-agent-preset/src/client/locales.ts +++ b/packages/client/ui-agent-preset/src/client/locales.ts @@ -100,7 +100,7 @@ export const zh: Record = { view: '查看', presetStandardName: '标准模式', presetStandardDescription: '功能完整的编码 Agent,支持文件编辑、Shell、文件与网页检索、Skills、计划、目标、子代理和工作流。', - presetCodeName: '代码模式', + presetCodeName: 'PTC 模式', presetCodeDescription: '具备标准模式的全部能力,并通过 Code Mode SDK 呈现工具,让模型用一个 TypeScript 程序组合多步操作。', presetMinimalName: '极简模式', presetMinimalDescription: '仅提供持久 bash 与 str_replace_editor 的双工具编码 Agent。', From 1ca6f68b173d8a4c2625ab060270ad08737aed48 Mon Sep 17 00:00:00 2001 From: ZiyaZhang <199893125+ZiyaZhang@users.noreply.github.com> Date: Wed, 12 Aug 2026 05:07:47 -0700 Subject: [PATCH 02/34] fix(web): guide clickable file references --- ...6-08-07-web-inline-file-mentions.i18n.yaml | 4 +-- .../2026-08-07-web-inline-file-mentions.md | 10 ++++-- .../2026-08-07-web-inline-file-mentions.zh.md | 10 ++++-- apps/web/tests/shipped-composition.e2e.ts | 18 ++++++++--- .../file-reference-prompt.expected.md | 1 + docs/config-catalog.md | 2 +- .../client/ui-deliverables/README.i18n.yaml | 4 +-- packages/client/ui-deliverables/README.md | 17 ++++++++-- packages/client/ui-deliverables/README.zh.md | 17 ++++++++-- packages/client/ui-deliverables/package.json | 4 ++- packages/client/ui-deliverables/src/index.ts | 31 +++++++++++++++---- .../client/ui-deliverables/src/invariant.ts | 7 ++--- .../tests/produced-files.client.spec.tsx | 5 +-- .../tests/prompt.client.spec.ts | 30 ++++++++++++++++++ packages/client/ui-deliverables/tsconfig.json | 3 ++ pnpm-lock.yaml | 3 ++ .../verify-package-readme-model-experience.ts | 1 - 17 files changed, 130 insertions(+), 37 deletions(-) create mode 100644 apps/web/tests/snapshots/web-runtime-context/file-reference-prompt.expected.md create mode 100644 packages/client/ui-deliverables/tests/prompt.client.spec.ts diff --git a/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.i18n.yaml b/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.i18n.yaml index b86faaa501..b97dae4740 100644 --- a/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.i18n.yaml @@ -2,5 +2,5 @@ # 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 .agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.md -2026-08-07-web-inline-file-mentions.md: cb51e6cfa5eebe0341b50c7638d51ac2d8641ba7 -2026-08-07-web-inline-file-mentions.zh.md: 160d3838fc8d02e57aa4371cb9d8a9ec7ccf6b5b +2026-08-07-web-inline-file-mentions.md: 0c7341e9aec688a0661fedb18731a1c172215f45 +2026-08-07-web-inline-file-mentions.zh.md: a9ef53933647feb27f9dde2d454166cf17de4fbe diff --git a/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.md b/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.md index cb51e6cfa5..0c7341e9ae 100644 --- a/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.md +++ b/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.md @@ -4,11 +4,11 @@ Status: implemented English | [中文](2026-08-07-web-inline-file-mentions.zh.md) -> Scope: linking inline-code tokens in the closing message's prose to the files the turn produced. Not in scope: recognizing paths in plain prose, linking files the turn did not produce, and mentions in streaming or mid-turn messages. +> Scope: guiding final responses to name primary output files as inline code, then linking those tokens to files the turn changed. Not in scope: recognizing paths in plain prose, linking files absent from successful mutation locations, and mentions in streaming or mid-turn messages. ## Problem -The produced-files row lists a turn's output, but the closing message usually also *names* the file in prose — as inline code, like `` `deepseek-homepage.html` `` — and that mention was inert text. The reader's eye lands on the sentence first; the affordance sat one row below it. +The produced-files row lists a turn's output, but the closing message usually also *names* the file in prose — as inline code, like `` `deepseek-homepage.html` `` — and that mention was inert text. The reader's eye lands on the sentence first; the affordance sat one row below it. The model was not told that this exact inline-code spelling activates the Web file opener, so producing the useful reference depended on habit. ## Decision @@ -16,13 +16,17 @@ The produced-files row lists a turn's output, but the closing message usually al **The renderer owns no vocabulary, and the provider is the deliverables plugin.** `MarkdownText` takes an optional `MarkdownFileMentions` resolver and consults it for inline-code tokens — after URL promotion, which wins, and never inside an anchor, where a button cannot nest. What names a file is decided behind the optional `chatFileMentions` service ui-conversation reaches via `ctx.get`: ui-deliverables provides it beside its turn-tail chain entry, so one cordis.yml line composes the row and the prose links in or out together, and ui-primitives gains no session concepts. Mentions apply to settled renders only — the streaming cache must not bake in handlers that could go stale, and the vocabulary is not final until the turn closes. The consumer memoizes the resolver on the closing seq rather than the growing transcript, so a settled message's cached parse survives stream appends. +**The provider also owns the model guidance for its accepted syntax.** The ui-deliverables Node half registers a static `ui:deliverable-file-references` section that asks the model to mention primary files from successful creation or modification calls in its final response and to write those and any other changed-file references as Markdown inline code, using the exact file-tool path or a basename only when it is unique within the Turn. The guidance deliberately says nothing about unrelated local-path formats. The shipped Web patch is the only composition that loads ui-deliverables, so the guidance exists exactly where the renderer exists; removing the package removes both. The row remains the correctness path when the model omits a mention, and the matching vocabulary still rejects anything not recorded by a successful mutation. + ## Alternatives considered - **Path-shaped regex over all prose** — links `package.json` mentioned abstractly and examples that were never written; every false positive is a click that opens nothing or the wrong file. The vocabulary approach cannot produce a dead link. - **Linking suffix matches (`out/index.html` mentioned as `index.html` in a subdirectory listing)** — deferred; exact path and unique basename cover the observed closing-message shapes, and a wider matcher can loosen later without breaking the seam. - **Resolving in ui-primitives against a passed path list** — puts matching policy in the generic renderer, where other consumers would inherit it unasked. The resolver contract keeps policy with the owner. - **Threading the vocabulary through the turn-tail chain** — the chain is a render dispatch below the message; mentions decorate markdown inside it, which only data reaching MarkdownText can do. The optional service is that data path, and its absence is the off state. +- **Registering the guidance in dsh-web-app** — makes the app bundle describe a feature-specific rendering syntax and allows the renderer and its prompt to drift or be composed independently. The feature package's existing Node half gives one cordis.yml row joint ownership. +- **Adding a post-turn model step to identify the output** — adds latency and another generation even though the final response already has the necessary file-tool history. One static prompt paragraph stays in the reusable prefix and asks the existing final generation to emit the accepted spelling. ## Consequences -The mention and the row are two affordances for one fact (full path as `title` on both); the mention itself wears the markdown sheet's anchor language — link-blue at rest, hover underline — because an at-rest underline collides with monospace descenders inside the code chip. `apps/web/tests/produced-file-mentions.e2e.ts` pins the assembled behavior with a built write-turn seed: unique basename links, ambiguous and unknown tokens stay inert; it does not click, for the produced-files restraint (the opener launches a real application). Mentions in mid-turn narration stay inert even for files the turn later produces, because the vocabulary attaches to the closing message only. The window-prepend edge — a window that starts mid-turn later gaining earlier same-turn writes — leaves a mention unlinked until remount, never wrongly linked. +The mention and the row are two affordances for one fact (full path as `title` on both); the mention itself wears the markdown sheet's anchor language — link-blue at rest, hover underline — because an at-rest underline collides with monospace descenders inside the code chip. The prompt section is constant for the package mount and therefore remains cacheable across Turns. The keyless shipped-Web composition snapshot pins the exact model-visible paragraph, while `apps/web/tests/produced-file-mentions.e2e.ts` pins the assembled rendering with a built write-turn seed: unique basename links, ambiguous and unknown tokens stay inert. Files created indirectly by terminal commands remain outside the vocabulary, even when the model names them. Mentions in mid-turn narration stay inert even for files the turn later produces, because the vocabulary attaches to the closing message only. The window-prepend edge — a window that starts mid-turn later gaining earlier same-turn writes — leaves a mention unlinked until remount, never wrongly linked. diff --git a/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.zh.md b/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.zh.md index 160d3838fc..a9ef539336 100644 --- a/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.zh.md +++ b/.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.zh.md @@ -4,11 +4,11 @@ Status: implemented [English](2026-08-07-web-inline-file-mentions.md) | 中文 -> 范围:把收尾消息正文中的行内代码 token 链接到本轮产出的文件。不在范围内:识别普通正文中的路径、链接本轮未产出的文件,以及流式或轮次中途消息里的提及。 +> 范围:引导最终回复以行内代码点名主要输出文件,再把这些 token 链接到本轮变更的文件。不在范围内:识别普通正文中的路径、链接成功修改位置中不存在的文件,以及流式或轮次中途消息里的提及。 ## 问题 -产物行列出了一轮的输出,但收尾消息通常也会在正文里*点名*文件——以行内代码形式,如 `` `deepseek-homepage.html` ``——而这个提及是死文本。读者的视线先落在句子上;可点击的交互却在下面一行。 +产物行列出了一轮的输出,但收尾消息通常也会在正文里*点名*文件——以行内代码形式,如 `` `deepseek-homepage.html` ``——而这个提及是死文本。读者的视线先落在句子上;可点击的交互却在下面一行。模型并不知道这种精确的行内代码写法会启用 Web 文件打开器,因此能否产生有用引用取决于模型习惯。 ## 决定 @@ -16,13 +16,17 @@ Status: implemented **渲染器不持有词表,提供方是 deliverables 插件。**`MarkdownText` 接受可选的 `MarkdownFileMentions` 解析器,对行内代码 token 询问它——URL 提升优先于解析器,且绝不在锚点内部(按钮不能嵌套在链接里)。什么算文件名的决定藏在 ui-conversation 经 `ctx.get` 触达的可选 `chatFileMentions` 服务背后:ui-deliverables 在其 turn-tail chain 注册项旁提供该服务,因此 cordis.yml 中的一行同时把产物行和正文链接组合进来或去掉,ui-primitives 不引入任何会话概念。提及只作用于已定稿的渲染——流式缓存不能固化可能过期的 handler,而且词表在轮次收尾前并不最终。消费方按收尾 seq 而非不断增长的 transcript(文本记录)记忆化解析器,因此已定稿消息的缓存解析在流式追加中得以保留。 +**提供方也拥有其所接受语法的模型指引。**ui-deliverables 的 Node 侧注册静态段落 `ui:deliverable-file-references`,要求模型在最终回复中点名来自成功创建或修改调用的主要文件,并将这些文件以及正文中提到的其他本轮变更文件写成 Markdown 行内代码:使用文件工具采用的精确路径,或仅在 basename 能唯一指代本轮文件时使用 basename。该指引刻意不涉及无关的本地路径格式。正式提供的组合中只有 Web patch 加载 ui-deliverables,因此提示词只存在于渲染器存在的地方;移除该包会同时移除两者。模型遗漏提及时,文件行仍承担正确性兜底;匹配词表仍拒绝成功修改记录之外的所有文件。 + ## 考虑过的替代方案 - **对全部正文跑路径形状的正则**——会把随口提到的 `package.json` 和从未写过的示例都链接上;每个误报都会带来一次点击,结果要么什么也没打开,要么打开了错误文件。词表方案不可能产生死链。 - **链接后缀匹配(子目录列表里把 `out/index.html` 写作 `index.html`)**——暂缓;精确路径加唯一 basename 已覆盖观察到的收尾消息形态,之后放宽匹配器不会破坏这道 seam。 - **在 ui-primitives 里对传入的路径列表做解析**——把匹配策略放进通用渲染器,其他消费方会被动继承。解析器约定让策略留在持有者手里。 - **经由 turn-tail chain 传递词表**——chain 是消息下方的渲染派发;提及要装饰的是消息内部的 markdown,只有抵达 MarkdownText 的数据才做得到。可选服务就是那条数据通路,它的缺席即关闭态。 +- **在 dsh-web-app 中注册指引**——会让应用组合包描述某个功能特有的渲染语法,也允许渲染器与提示词分别组合或产生漂移。该功能包现有的 Node 侧让 cordis.yml 中的一项可以共同持有两者。 +- **增加一次轮次结束后的模型调用来识别输出**——即使最终回复已经拥有所需的文件工具历史,仍会增加延迟和一次生成。一个静态提示词段落可以留在可复用前缀中,并要求现有的最终生成输出渲染器接受的写法。 ## 后果 -提及与产物行是同一事实的两个交互面(两者都以完整路径作 `title`);提及本身采用 markdown 样式表的锚点语言——静止为链接蓝、悬停出下划线——因为静止下划线在 code 胶囊里会压住等宽字的下伸部。`apps/web/tests/produced-file-mentions.e2e.ts` 用构造的写入轮次 seed 钉住组装后的行为:唯一 basename 成链,歧义与未知 token 保持死文本;它不执行点击,沿用产物行测试不启动外部应用的限制(opener 会启动真实应用)。轮次中途叙述里的提及即使命名了本轮后来产出的文件也保持死文本,因为词表只挂在收尾消息上。窗口前插的边界——从轮次中途开始的窗口后来补入了同轮更早的写入——只会让提及在重挂载前暂不成链,绝不会错链。 +提及与产物行是同一事实的两个交互面(两者都以完整路径作 `title`);提及本身采用 markdown 样式表的锚点语言——静止为链接蓝、悬停出下划线——因为静止下划线在 code 胶囊里会压住等宽字的下伸部。提示词段落在本包加载期间保持不变,因此可跨 Turn 复用缓存。无密钥的正式 Web 组合快照钉住模型可见段落的精确文本,`apps/web/tests/produced-file-mentions.e2e.ts` 则用构造的写入轮次 seed 钉住组装后的渲染行为:唯一 basename 成链,歧义与未知 token 保持死文本。终端命令间接创建的文件即使被模型点名,仍不在词表中。轮次中途叙述里的提及即使命名了本轮后来产出的文件也保持死文本,因为词表只挂在收尾消息上。窗口前插的边界——从轮次中途开始的窗口后来补入了同轮更早的写入——只会让提及在重挂载前暂不成链,绝不会错链。 diff --git a/apps/web/tests/shipped-composition.e2e.ts b/apps/web/tests/shipped-composition.e2e.ts index ee00353ef8..aa43d350fb 100644 --- a/apps/web/tests/shipped-composition.e2e.ts +++ b/apps/web/tests/shipped-composition.e2e.ts @@ -1,9 +1,11 @@ // Boots the shipped Web composition over the built dist this lane already uses // and asserts what that composition produces: the model-visible tool catalog -// and the sandbox/approval knobs it ships with. No browser and no model call — -// these are composition facts, and the browser scenarios in this lane cover the -// surface itself. +// and file-reference guidance plus the sandbox/approval knobs it ships with. +// No browser and no model call — these are composition facts, and the browser +// scenarios in this lane cover the surface itself. +import { readFileSync } from 'node:fs' import { tmpdir } from 'node:os' +import { fileURLToPath } from 'node:url' import { afterEach, expect, it } from 'vitest' import { CallId } from '@deepseek-ai/dsh-llm' import { canonicalPath, writableRoots } from '@deepseek-ai/dsh-sandbox' @@ -15,8 +17,13 @@ import type {} from '@deepseek-ai/dsh-user-approval' import type {} from '@deepseek-ai/dsh-permission' import type {} from '@deepseek-ai/dsh-agent-presets' import type {} from '@deepseek-ai/dsh-commands' +import type {} from '@deepseek-ai/dsh-system-prompt' import { launchWebScaffold, type WebScaffold } from './scaffold.ts' +const FILE_REFERENCE_PROMPT = fileURLToPath(new URL( + './snapshots/web-runtime-context/file-reference-prompt.expected.md', import.meta.url, +)) + /** * The catalog the shipped Web composition puts in front of the model, minus the * ripgrep-dependent pair below. The absences are deliberate, not incidental @@ -66,7 +73,7 @@ afterEach(async () => { scaffold = undefined }) -it('assembles the shipped Web catalog with the confined access default', async () => { +it('assembles the shipped Web catalog, file-reference guidance, and confined access default', async () => { scaffold = await launchWebScaffold() const ctx = scaffold.ctx // The catalog belongs to an AGENT, not to the process: every model-facing row @@ -85,6 +92,9 @@ it('assembles the shipped Web catalog with the confined access default', async ( // The packaged ripgrep binary ships with the dependency, so the pair is a // fixed roster member on every host. expect(names.filter(name => RIPGREP_TOOLS.includes(name))).toEqual(RIPGREP_TOOLS) + const fileReferenceSection = (await ctx.systemPrompt.assemble({ scope: handle.agent })).sections + .find(section => section.name === 'ui:deliverable-file-references') + expect(fileReferenceSection?.text).toBe(readFileSync(FILE_REFERENCE_PROMPT, 'utf8').trimEnd()) } finally { await handle.dispose() } diff --git a/apps/web/tests/snapshots/web-runtime-context/file-reference-prompt.expected.md b/apps/web/tests/snapshots/web-runtime-context/file-reference-prompt.expected.md new file mode 100644 index 0000000000..6561157aec --- /dev/null +++ b/apps/web/tests/snapshots/web-runtime-context/file-reference-prompt.expected.md @@ -0,0 +1 @@ +When you successfully create or modify files, mention the primary outputs in your final response. To make those and any other changed-file references clickable in Web, format them as Markdown inline code using the exact file-tool path, or a basename when unique among the files changed in that turn. diff --git a/docs/config-catalog.md b/docs/config-catalog.md index 3eb59072b7..a10089b686 100644 --- a/docs/config-catalog.md +++ b/docs/config-catalog.md @@ -2806,7 +2806,7 @@ These load from a `cordis.yml` entry with no `config:` block; they declare no co - `@deepseek-ai/dsh-client-ui-agent-preset` ([`packages/client/ui-agent-preset/src/index.ts`](../packages/client/ui-agent-preset/src/index.ts)) - `@deepseek-ai/dsh-client-ui-command` ([`packages/client/ui-command/src/index.ts`](../packages/client/ui-command/src/index.ts)) - `@deepseek-ai/dsh-client-ui-conversation` ([`packages/client/ui-conversation/src/index.ts`](../packages/client/ui-conversation/src/index.ts)) -- `@deepseek-ai/dsh-client-ui-deliverables` ([`packages/client/ui-deliverables/src/index.ts`](../packages/client/ui-deliverables/src/index.ts)) +- `@deepseek-ai/dsh-client-ui-deliverables` — requires `systemPrompt` ([`packages/client/ui-deliverables/src/index.ts`](../packages/client/ui-deliverables/src/index.ts)) - `@deepseek-ai/dsh-client-ui-directory-picker` ([`packages/client/ui-directory-picker/src/index.ts`](../packages/client/ui-directory-picker/src/index.ts)) - `@deepseek-ai/dsh-client-ui-directory-picker-native` ([`packages/client/ui-directory-picker-native/src/index.ts`](../packages/client/ui-directory-picker-native/src/index.ts)) - `@deepseek-ai/dsh-client-ui-feedback` ([`packages/client/ui-feedback/src/index.ts`](../packages/client/ui-feedback/src/index.ts)) diff --git a/packages/client/ui-deliverables/README.i18n.yaml b/packages/client/ui-deliverables/README.i18n.yaml index cfa85256ec..70b3f889bf 100644 --- a/packages/client/ui-deliverables/README.i18n.yaml +++ b/packages/client/ui-deliverables/README.i18n.yaml @@ -2,5 +2,5 @@ # 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 packages/client/ui-deliverables/README.md -README.md: 9cfcde9510c5d6814d5b42fd58a0520ea37b8679 -README.zh.md: 4e09524e269df31cdabce0d5f6e6900d23305265 +README.md: e7118eac75f31b3ffc3f2434371dba06f029d241 +README.zh.md: 0c41170ef38331166f6ad87df0c3e5976200eaf9 diff --git a/packages/client/ui-deliverables/README.md b/packages/client/ui-deliverables/README.md index 9cfcde9510..e7118eac75 100644 --- a/packages/client/ui-deliverables/README.md +++ b/packages/client/ui-deliverables/README.md @@ -2,7 +2,7 @@ English | [中文](README.zh.md) -Produced-files feature owner: registers the deliverables row a finished turn ends with into the chat view's `conversation.chat.turnTail` hole. All policy lives here; removing this plugin's line from cordis.yml removes the surface entirely, and the owning view renders an empty hole at zero cost. +Produced-files and clickable-reference feature owner. The Node half registers final-response guidance with the system-prompt registry; the browser half registers the deliverables row a finished turn ends with into the chat view's `conversation.chat.turnTail` hole and links matching inline-code references in the closing prose. The shipped Web patch is the only composition that loads this package. Removing its one cordis.yml entry removes the guidance, row, and prose links together. `deliverablesDefinition` folds each Turn's successful mutation calls into engine-published `DeliverablesTurnData`; `producedForClosing` reads that data with the closing Assistant seq. The vocabulary is the mutation tools' own follow-along `locations`, never the closing prose: a produced file is listed whether or not the model remembered to name it. A mutation is recognized by render intent, not tool name — a diff card, or a generic card whose `kind` is `edit` (the shape `str_replace_editor`'s insert presents) — so a new mutation tool joins by declaring what it does. Reads, deletes, and failed calls contribute nothing; a path appears once per Turn in first-seen order. The Conversation Location index owns Turn membership, so a Turn that mutates and then ends without content text cannot spill into the next Turn's row. @@ -10,15 +10,26 @@ Produced-files feature owner: registers the deliverables row a finished turn end The closing prose carries the same vocabulary. This plugin provides the `chatFileMentions` service the chat view consults per closing message: `producedFileMentions` resolves an inline-code token by exact path, or by being exactly the basename of exactly one produced path — a basename two paths share stays inert rather than guessing, so a mention link can never open the wrong file or 404. A resolved mention keeps its code chip and takes the markdown sheet's link language — link-blue at rest, underlined on hover, exactly like URL-promoted inline code — with the full path as its `title`; mentions never render inside anchors or streaming text. Decision record: the [inline file mentions Agent Note](../../../.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.md). +The Node half registers the static `ui:deliverable-file-references` system-prompt section. It asks the model to mention the primary files it successfully created or modified and to write those and any other changed-file references as Markdown inline code, using the exact file-tool path or a basename only when unique within the Turn. The guidance makes the renderer's accepted syntax explicit; it does not govern unrelated path discussions or widen the renderer's successful-mutation vocabulary. + ## Model Experience -None, as the row is a pure client derivation over already-logged tool metadata and nothing here reaches a model request. +### Clickable file-reference guidance + +#### What the model sees + +One fixed paragraph instructs the model to name primary files from successful creation or modification calls in its final response and to format those and any other changed-file references as exact-path or unique-basename Markdown inline code, such as `out/report.html`. + +#### Token effect + +One fixed prompt paragraph whenever this package is loaded; no tool schema, tool result, or per-Turn context is added. #### KV Cache effect -None; this package neither assembles nor sends provider requests. +The section is static at order 190 for the lifetime of the package mount, so it remains in the reusable prompt prefix and does not change across Turns. ## Known Limitations and Deferred Work - **Mention matching is exact path or unique basename only.** A suffix mention (`out/index.html` written as `index.html` resolves; `deep/out/index.html` written as `out/index.html` does not) stays inert; widening the matcher is deferred until a real closing-message shape needs it. +- **Files created indirectly by terminal commands remain outside the matching vocabulary.** Naming such a file in inline code does not make it clickable unless a successful mutation location also records that path. - **Native folder handoff targets the Host desktop.** A browser reached through a non-loopback authority omits the action, as does a deployment reporting no native opener. SSH forwarding that makes a remote Host look loopback-local must set the gateway's `nativeOpen: false`; so must a headless macOS/Windows Host, a WSL deployment without working Windows interop, or any Linux desktop whose display/opener probe is a false positive. Identifying the operator-visible desktop remains deployment policy. diff --git a/packages/client/ui-deliverables/README.zh.md b/packages/client/ui-deliverables/README.zh.md index 4e09524e26..0c41170ef3 100644 --- a/packages/client/ui-deliverables/README.zh.md +++ b/packages/client/ui-deliverables/README.zh.md @@ -2,7 +2,7 @@ [English](README.md) | 中文 -产出文件功能的属主:把已完成轮次末尾的产出文件行注册到 chat 视图的 `conversation.chat.turnTail` slot 中。全部策略都在本包内;从 cordis.yml 中删去本插件那一行即可整体移除该界面,属主视图无需额外开销即可渲染空 slot。 +产出文件与可点击文件引用功能的属主。Node 侧向系统提示词 registry 注册最终回复指引;浏览器侧把已完成轮次末尾的产出文件行注册到 chat 视图的 `conversation.chat.turnTail` slot,并将收尾正文中匹配的行内代码引用转换为链接。正式提供的组合中只有 Web patch 加载本包;从 cordis.yml 中删去这一项会同时移除提示词、文件行与正文链接。 `deliverablesDefinition` 把每个轮次中成功的修改调用折叠进引擎发布的 `DeliverablesTurnData`;`producedForClosing` 结合收尾 Assistant 的 seq 读取这份数据。依据的是修改工具自身附带的 `locations`,而不是收尾正文:无论模型是否记得点名,产出文件都会被列出。修改操作按渲染意图而非工具名识别:diff 卡片,或 `kind` 为 `edit` 的通用卡片(即 `str_replace_editor` 的 insert 操作所呈现的形态);因此新的修改工具只需声明自身行为即可加入。读取、删除和失败的调用不贡献任何条目;同一路径在一个轮次内按首见顺序只出现一次。Conversation Location 索引负责维护轮次归属关系,因此一个轮次即使先修改文件、随后没有正文内容就结束,也不会溢进下一个轮次的行里。 @@ -10,15 +10,26 @@ 收尾正文承载同一份词表。本插件提供供 chat 视图按收尾消息查询的 `chatFileMentions` 服务:`producedFileMentions` 按精确路径解析行内代码 token,或当 token 恰好等于某条产出路径的 basename,且这样的路径仅有一条时解析——两条路径共享同一 basename 时,文本保持不可点击而不作猜测,因此提及链接永远不会打开错误的文件,也不会导致 404。解析成功的提及保留代码标签,并采用 Markdown 样式表的链接样式:静止时为链接蓝色,悬停时显示下划线,与 URL 提升的行内代码完全一致——完整路径作为其 `title`;提及绝不会渲染在链接内部或流式文本中。决策记录:[行内文件提及 Agent Note](../../../.agents/notes/implemented/feature/2026-08-07-web-inline-file-mentions.md)。 +Node 侧注册静态系统提示词段落 `ui:deliverable-file-references`。它要求模型点名成功创建或修改的主要文件,并将这些文件以及正文中提到的其他本轮变更文件写成 Markdown 行内代码:使用文件工具采用的精确路径,或仅在 basename 能唯一指代本轮文件时使用 basename。该提示词只向模型说明渲染器接受的语法;它不约束无关的路径讨论,也不会扩大渲染器的成功修改词表。 + ## 模型体验 -无。该行是对已记录工具元数据的纯客户端派生,这里没有任何内容进入模型请求。 +### 可点击文件引用指引 + +#### 模型看到的内容 + +一段固定提示词要求模型在最终回复中点名成功创建或修改的主要文件,并将这些文件以及正文中提到的其他本轮变更文件写成采用精确路径或唯一 basename 的 Markdown 行内代码,例如 `out/report.html`。 + +#### Token 影响 + +加载本包时增加一段固定提示词;不增加工具 schema、工具结果或按 Turn 变化的上下文。 #### KV Cache 影响 -无;该包既不组装也不发送提供方请求。 +该段落在本包加载期间始终以顺序 190 保持静态,因此留在可复用的提示词前缀中,不会随 Turn 改变。 ## 已知限制与暂缓事项 - **提及匹配只认精确路径或唯一 basename。**后缀式提及(`out/index.html` 写作 `index.html` 可解析;`deep/out/index.html` 写作 `out/index.html` 则不行)保持不可点击;等真实的收尾消息形态产生需求后再放宽匹配规则。 +- **终端命令间接创建的文件仍不在匹配词表内。**除非某个成功修改位置也记录了该路径,否则在行内代码中点名这类文件不会使其可点击。 - **原生文件夹交接以 Host 桌面为目标。**经非 loopback 权威访问的浏览器会省略该操作,报告没有原生打开器的部署也一样。若 SSH 转发让远端 Host 看似处于本机 loopback,部署必须为网关设置 `nativeOpen: false`;无界面的 macOS/Windows Host、Windows interop 不可用的 WSL,或 display/opener 探测误报的 Linux 桌面也必须这样配置。识别操作者实际可见的桌面仍属于部署策略。 diff --git a/packages/client/ui-deliverables/package.json b/packages/client/ui-deliverables/package.json index 4d7ea0d314..2a0559fc7b 100644 --- a/packages/client/ui-deliverables/package.json +++ b/packages/client/ui-deliverables/package.json @@ -1,6 +1,6 @@ { "name": "@deepseek-ai/dsh-client-ui-deliverables", - "description": "Produced-files turn tail: the deliverables row a finished turn ends with", + "description": "Produced-files turn tail and clickable final-response file references for Web", "version": "0.0.1-rc.2", "publishConfig": { "access": "restricted" @@ -55,6 +55,7 @@ "@deepseek-ai/dsh-client-ui-conversation": "workspace:^", "@deepseek-ai/dsh-client-ui-slots": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", + "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/cordis": "workspace:^" }, "devDependencies": { @@ -65,6 +66,7 @@ "@deepseek-ai/dsh-client-ui-conversation": "workspace:^", "@deepseek-ai/dsh-client-ui-slots": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", + "@deepseek-ai/dsh-system-prompt": "workspace:^", "@types/react": "~18.3.1", "@deepseek-ai/cordis": "workspace:^" }, diff --git a/packages/client/ui-deliverables/src/index.ts b/packages/client/ui-deliverables/src/index.ts index c6ea80fa21..6e6c387803 100644 --- a/packages/client/ui-deliverables/src/index.ts +++ b/packages/client/ui-deliverables/src/index.ts @@ -1,9 +1,28 @@ /** - * Deliverables plugin, node half. Pure UI plugin: the empty apply exists so - * the plugin appears in the host cordis.yml / Loader; the browser half ships - * via exports["./client"], discovered through the package.json dsh.client - * declaration. + * Deliverables plugin, node half. Registers the response-format guidance that + * lets the browser half recognize final-response file references. The browser + * half ships via exports["./client"], discovered through the package.json + * dsh.client declaration. */ -/** Host plugin body — no host-side behavior for this surface plugin. */ -export function apply(): void {} +import type { Context } from '@deepseek-ai/cordis' +import type {} from '@deepseek-ai/dsh-system-prompt' + +/** Services required for the model guidance paired with the browser renderer. */ +export const inject = ['systemPrompt'] + +/** Stable final-response guidance owned by the matching renderer. */ +const FILE_REFERENCE_PROMPT = 'When you successfully create or modify files, mention the primary outputs in your final response. ' + + 'To make those and any other changed-file references clickable in Web, format them as Markdown inline code using the exact file-tool path, or a basename when unique among the files changed in that turn.' + +/** + * Register model guidance for the file-reference renderer shipped by this package. + * @param ctx - host context carrying the system-prompt registry. + */ +export function apply(ctx: Context): void { + ctx.systemPrompt.section({ + name: 'ui:deliverable-file-references', + order: 190, + text: FILE_REFERENCE_PROMPT, + }) +} diff --git a/packages/client/ui-deliverables/src/invariant.ts b/packages/client/ui-deliverables/src/invariant.ts index d14e474ca3..7fa5eaa216 100644 --- a/packages/client/ui-deliverables/src/invariant.ts +++ b/packages/client/ui-deliverables/src/invariant.ts @@ -15,10 +15,9 @@ export const name = 'client-ui-deliverables-invariant' export const inject = ['invariants'] /** - * No runtime invariant: one slot registration and one dictionary - * registration, both effect-owned with disposal proven by the HMR-safety - * spec — the plugin emits no cordis events and owns no cross-plugin mutable - * state. + * No runtime invariant: the prompt section, slot, dictionary, event + * definition, and optional service registrations are effect-owned with + * disposal proven by their plugin specs; this package owns no mutable state. */ const install: InvariantInstaller = () => {} diff --git a/packages/client/ui-deliverables/tests/produced-files.client.spec.tsx b/packages/client/ui-deliverables/tests/produced-files.client.spec.tsx index 468dd242fa..89cbfb8a58 100644 --- a/packages/client/ui-deliverables/tests/produced-files.client.spec.tsx +++ b/packages/client/ui-deliverables/tests/produced-files.client.spec.tsx @@ -27,7 +27,6 @@ import { type DeliverablesTurnData, } from '../src/client/turn-deliverables.ts' import { apply, inject } from '../src/client/index.ts' -import { apply as applyNode } from '../src/index.ts' import { apply as applyInvariant } from '../src/invariant.ts' import { en, zh } from '../src/client/locales.ts' @@ -438,9 +437,7 @@ describe('producedFileMentions resolver', () => { }) describe('package shells', () => { - it('the node half mounts inert and the invariant companion registers ownership', async () => { - // The node half is deliberately inert; mounting it must simply not throw. - applyNode() + it('the invariant companion registers ownership', async () => { const registered: string[] = [] const ctx = new Context() ctx.provide('invariants') diff --git a/packages/client/ui-deliverables/tests/prompt.client.spec.ts b/packages/client/ui-deliverables/tests/prompt.client.spec.ts new file mode 100644 index 0000000000..2ae6f0f1e3 --- /dev/null +++ b/packages/client/ui-deliverables/tests/prompt.client.spec.ts @@ -0,0 +1,30 @@ +/** Node-half coverage for the model guidance paired with Web file references. */ + +import { Context } from '@deepseek-ai/cordis' +import { afterEach, describe, expect, it } from 'vitest' +import SystemPrompt from '@deepseek-ai/dsh-system-prompt' +import { apply, inject } from '../src/index.ts' + +let ctx: Context | undefined + +afterEach(async () => { + await ctx?.fiber.dispose() + ctx = undefined +}) + +describe('ui-deliverables node plugin', () => { + it('registers final-response file-reference guidance only while mounted', async () => { + ctx = new Context() + await ctx.plugin(SystemPrompt, { persona: '' }) + const mounted = ctx.plugin({ apply, inject }) + await mounted.await() + + const section = (await ctx.systemPrompt.assemble()).sections + .find(entry => entry.name === 'ui:deliverable-file-references') + expect(section?.text).toMatchInlineSnapshot('"When you successfully create or modify files, mention the primary outputs in your final response. To make those and any other changed-file references clickable in Web, format them as Markdown inline code using the exact file-tool path, or a basename when unique among the files changed in that turn."') + + await mounted.dispose() + expect((await ctx.systemPrompt.assemble()).sections + .some(entry => entry.name === 'ui:deliverable-file-references')).toBe(false) + }) +}) diff --git a/packages/client/ui-deliverables/tsconfig.json b/packages/client/ui-deliverables/tsconfig.json index 3fa938986f..5a403871cd 100644 --- a/packages/client/ui-deliverables/tsconfig.json +++ b/packages/client/ui-deliverables/tsconfig.json @@ -25,6 +25,9 @@ }, { "path": "../../support/invariants" + }, + { + "path": "../../core/system-prompt" } ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 364a560e38..8ca3fabc56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2213,6 +2213,9 @@ importers: '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants + '@deepseek-ai/dsh-system-prompt': + specifier: workspace:^ + version: link:../../core/system-prompt '@types/react': specifier: ~18.3.1 version: 18.3.31 diff --git a/scripts/verify-package-readme-model-experience.ts b/scripts/verify-package-readme-model-experience.ts index 813175b307..a4a8234fc2 100644 --- a/scripts/verify-package-readme-model-experience.ts +++ b/scripts/verify-package-readme-model-experience.ts @@ -73,7 +73,6 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly> = { 'packages/client/ui-conversation': { kind: 'none', reason: 'Browser-side UI plugin layer; registers nothing model-facing.' }, 'packages/client/ui-feedback': { kind: 'none', reason: 'Browser-side controls over the message-feedback sidecar; ratings and notes never enter the Session log, model context, or telemetry.' }, 'packages/client/ui-tool': { kind: 'none', reason: 'Browser-side Tool presentation layer; renders logged calls without changing model context.' }, - 'packages/client/ui-deliverables': { kind: 'none', reason: 'Browser-side UI plugin layer; registers nothing model-facing.' }, 'packages/client/ui-task': { kind: 'none', reason: 'Browser-side read-only projection of ctx.tasks records; dsh-tool-tasks owns the model-facing behavior.' }, 'packages/client/ui-workflow-run': { kind: 'none', reason: 'Browser-side UI plugin layer; renders durable workflow records without changing model context.' }, 'packages/client/ui-slash': { kind: 'none', reason: 'Browser-side UI plugin layer; registers nothing model-facing.' }, From d6fc55ad863916ade46102860bfc1ced516c8205 Mon Sep 17 00:00:00 2001 From: ZiyaZhang <199893125+ZiyaZhang@users.noreply.github.com> Date: Wed, 12 Aug 2026 08:39:09 -0700 Subject: [PATCH 03/34] docs: refresh generated references --- docs/config-catalog.i18n.yaml | 4 ++-- docs/config-catalog.zh.md | 2 +- docs/module-graph.i18n.yaml | 4 ++-- docs/module-graph.md | 3 ++- docs/module-graph.zh.md | 3 ++- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/config-catalog.i18n.yaml b/docs/config-catalog.i18n.yaml index 33fae42ac2..bb542a0ab7 100644 --- a/docs/config-catalog.i18n.yaml +++ b/docs/config-catalog.i18n.yaml @@ -2,5 +2,5 @@ # 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 docs/config-catalog.md -config-catalog.md: f075a5c22049df1696a1849cd88bd3b783adde21 -config-catalog.zh.md: 952a77df3ba279155b4364a083917f816efd2d63 +config-catalog.md: bdec02cae2afd13bbe9ef041d95c6c30164f8fc0 +config-catalog.zh.md: 11769b07652859058d16ec7309411e2f05eca254 diff --git a/docs/config-catalog.zh.md b/docs/config-catalog.zh.md index 952a77df3b..11769b0765 100644 --- a/docs/config-catalog.zh.md +++ b/docs/config-catalog.zh.md @@ -2807,7 +2807,7 @@ export interface Config { - `@deepseek-ai/dsh-client-ui-agent-preset`([`packages/client/ui-agent-preset/src/index.ts`](../packages/client/ui-agent-preset/src/index.ts)) - `@deepseek-ai/dsh-client-ui-command`([`packages/client/ui-command/src/index.ts`](../packages/client/ui-command/src/index.ts)) - `@deepseek-ai/dsh-client-ui-conversation`([`packages/client/ui-conversation/src/index.ts`](../packages/client/ui-conversation/src/index.ts)) -- `@deepseek-ai/dsh-client-ui-deliverables`([`packages/client/ui-deliverables/src/index.ts`](../packages/client/ui-deliverables/src/index.ts)) +- `@deepseek-ai/dsh-client-ui-deliverables` — 需要 `systemPrompt`([`packages/client/ui-deliverables/src/index.ts`](../packages/client/ui-deliverables/src/index.ts)) - `@deepseek-ai/dsh-client-ui-directory-picker`([`packages/client/ui-directory-picker/src/index.ts`](../packages/client/ui-directory-picker/src/index.ts)) - `@deepseek-ai/dsh-client-ui-directory-picker-native`([`packages/client/ui-directory-picker-native/src/index.ts`](../packages/client/ui-directory-picker-native/src/index.ts)) - `@deepseek-ai/dsh-client-ui-feedback`([`packages/client/ui-feedback/src/index.ts`](../packages/client/ui-feedback/src/index.ts)) diff --git a/docs/module-graph.i18n.yaml b/docs/module-graph.i18n.yaml index b528a4356d..7f7c5d902f 100644 --- a/docs/module-graph.i18n.yaml +++ b/docs/module-graph.i18n.yaml @@ -2,5 +2,5 @@ # 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 docs/module-graph.md -module-graph.md: 5197a184f2be283e3bb57de91d4a4d3cb22e51b2 -module-graph.zh.md: 3b312b731d32ed71674d800c35a5868e0b5d94ee +module-graph.md: bee4af67d5c2895bb03f584daca7fc7cf43a5cd3 +module-graph.zh.md: 506645d45fae4b5dcd301e11c4b2b40a9361bb09 diff --git a/docs/module-graph.md b/docs/module-graph.md index 5197a184f2..bee4af67d5 100644 --- a/docs/module-graph.md +++ b/docs/module-graph.md @@ -1269,6 +1269,7 @@ flowchart TD pkg_client_ui_deliverables --> pkg_client_ui_conversation pkg_client_ui_deliverables --> pkg_client_ui_slots pkg_client_ui_deliverables --> pkg_invariants + pkg_client_ui_deliverables --> pkg_system_prompt pkg_client_ui_feedback --> pkg_api_remotes pkg_client_ui_feedback --> pkg_client_connection pkg_client_ui_feedback --> pkg_client_locale @@ -1579,7 +1580,7 @@ flowchart TD | [`client-ui-settings-general`](../packages/client/ui-settings-general) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`client-ui-slots`](../packages/client/ui-slots), [`client-web-react`](../packages/client/web-react), [`invariants`](../packages/support/invariants) | | [`client-ui-agent-preset`](../packages/client/ui-agent-preset) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-slots`](../packages/client/ui-slots), [`client-web-react`](../packages/client/web-react), [`invariants`](../packages/support/invariants) | | [`client-ui-command`](../packages/client/ui-command) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slash`](../packages/client/ui-slash), [`client-ui-slots`](../packages/client/ui-slots), [`commands`](../packages/interaction/commands), [`invariants`](../packages/support/invariants) | -| [`client-ui-deliverables`](../packages/client/ui-deliverables) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants) | +| [`client-ui-deliverables`](../packages/client/ui-deliverables) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants), [`system-prompt`](../packages/core/system-prompt) | | [`client-ui-feedback`](../packages/client/ui-feedback) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants), [`message-feedback`](../packages/feedback/message-feedback), [`type-meta`](../packages/typert/type-meta) | | [`client-ui-goal`](../packages/client/ui-goal) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`commands`](../packages/interaction/commands), [`goal`](../packages/goal/goal), [`invariants`](../packages/support/invariants) | | [`client-ui-plan`](../packages/client/ui-plan) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants), [`plan-mode`](../packages/plan/plan-mode) | diff --git a/docs/module-graph.zh.md b/docs/module-graph.zh.md index 3b312b731d..506645d45f 100644 --- a/docs/module-graph.zh.md +++ b/docs/module-graph.zh.md @@ -1271,6 +1271,7 @@ flowchart TD pkg_client_ui_deliverables --> pkg_client_ui_conversation pkg_client_ui_deliverables --> pkg_client_ui_slots pkg_client_ui_deliverables --> pkg_invariants + pkg_client_ui_deliverables --> pkg_system_prompt pkg_client_ui_feedback --> pkg_api_remotes pkg_client_ui_feedback --> pkg_client_connection pkg_client_ui_feedback --> pkg_client_locale @@ -1581,7 +1582,7 @@ flowchart TD | [`client-ui-settings-general`](../packages/client/ui-settings-general) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`client-ui-slots`](../packages/client/ui-slots), [`client-web-react`](../packages/client/web-react), [`invariants`](../packages/support/invariants) | | [`client-ui-agent-preset`](../packages/client/ui-agent-preset) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-slots`](../packages/client/ui-slots), [`client-web-react`](../packages/client/web-react), [`invariants`](../packages/support/invariants) | | [`client-ui-command`](../packages/client/ui-command) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slash`](../packages/client/ui-slash), [`client-ui-slots`](../packages/client/ui-slots), [`commands`](../packages/interaction/commands), [`invariants`](../packages/support/invariants) | -| [`client-ui-deliverables`](../packages/client/ui-deliverables) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants) | +| [`client-ui-deliverables`](../packages/client/ui-deliverables) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants), [`system-prompt`](../packages/core/system-prompt) | | [`client-ui-feedback`](../packages/client/ui-feedback) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants), [`message-feedback`](../packages/feedback/message-feedback), [`type-meta`](../packages/typert/type-meta) | | [`client-ui-goal`](../packages/client/ui-goal) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`commands`](../packages/interaction/commands), [`goal`](../packages/goal/goal), [`invariants`](../packages/support/invariants) | | [`client-ui-plan`](../packages/client/ui-plan) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants), [`plan-mode`](../packages/plan/plan-mode) | From 238e900776ff0743f0a0b6a83414c526e46e844a Mon Sep 17 00:00:00 2001 From: ZiyaZhang <199893125+ZiyaZhang@users.noreply.github.com> Date: Wed, 12 Aug 2026 08:43:25 -0700 Subject: [PATCH 04/34] ci: retrigger after stale merge ref From a2d0f7f41121ee81911dd1badbf248edd3f2ab70 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Thu, 13 Aug 2026 00:36:22 +0800 Subject: [PATCH 05/34] refactor: apply repository naming contract Apply the accepted pre-release package, service, type, directory, and role renames as one repository-wide change. --- ...026-06-11-event-sourced-sessions.i18n.yaml | 4 +- .../2026-06-11-event-sourced-sessions.md | 2 +- .../2026-06-11-event-sourced-sessions.zh.md | 2 +- .../2026-06-13-capability-seams.i18n.yaml | 4 +- .../2026-06-13-capability-seams.md | 8 +- .../2026-06-13-capability-seams.zh.md | 6 +- .../2026-06-14-session-persistence.i18n.yaml | 4 +- .../2026-06-14-session-persistence.md | 2 +- .../2026-06-14-session-persistence.zh.md | 2 +- ...06-17-filesystem-capability-seam.i18n.yaml | 4 +- .../2026-06-17-filesystem-capability-seam.md | 32 +- ...026-06-17-filesystem-capability-seam.zh.md | 32 +- ...ifecycle-and-ownership-contracts.i18n.yaml | 4 +- ...agent-lifecycle-and-ownership-contracts.md | 8 +- ...nt-lifecycle-and-ownership-contracts.zh.md | 4 +- .../2026-06-18-session-surface.i18n.yaml | 4 +- .../2026-06-18-session-surface.md | 2 +- .../2026-06-18-session-surface.zh.md | 2 +- .../2026-06-20-branded-ids.i18n.yaml | 4 +- .../architecture/2026-06-20-branded-ids.md | 16 +- .../architecture/2026-06-20-branded-ids.zh.md | 16 +- ...eneric-long-running-tool-runtime.i18n.yaml | 4 +- ...06-20-generic-long-running-tool-runtime.md | 64 +- ...20-generic-long-running-tool-runtime.zh.md | 62 +- ...-21-bounded-llm-request-recovery.i18n.yaml | 4 +- ...2026-06-21-bounded-llm-request-recovery.md | 4 +- ...6-06-21-bounded-llm-request-recovery.zh.md | 4 +- ...andatory-app-attribution-headers.i18n.yaml | 4 +- ...06-21-mandatory-app-attribution-headers.md | 2 +- ...21-mandatory-app-attribution-headers.zh.md | 2 +- .../2026-06-24-web-capability-seam.i18n.yaml | 4 +- .../2026-06-24-web-capability-seam.md | 32 +- .../2026-06-24-web-capability-seam.zh.md | 32 +- ...06-26-file-context-as-event-gate.i18n.yaml | 4 +- .../2026-06-26-file-context-as-event-gate.md | 58 +- ...026-06-26-file-context-as-event-gate.zh.md | 58 +- ...ash-stdin-env-trusted-plugin-api.i18n.yaml | 4 +- ...06-30-bash-stdin-env-trusted-plugin-api.md | 6 +- ...30-bash-stdin-env-trusted-plugin-api.zh.md | 6 +- ...6-07-02-tool-render-intent-union.i18n.yaml | 4 +- .../2026-07-02-tool-render-intent-union.md | 4 +- .../2026-07-02-tool-render-intent-union.zh.md | 2 +- ...bles-and-tool-guidance-ownership.i18n.yaml | 4 +- ...t-variables-and-tool-guidance-ownership.md | 4 +- ...ariables-and-tool-guidance-ownership.zh.md | 4 +- ...6-07-05-reconstructable-requests.i18n.yaml | 4 +- .../2026-07-05-reconstructable-requests.md | 4 +- .../2026-07-05-reconstructable-requests.zh.md | 4 +- ...6-07-06-timeout-deadline-library.i18n.yaml | 4 +- .../2026-07-06-timeout-deadline-library.md | 10 +- .../2026-07-06-timeout-deadline-library.zh.md | 10 +- ...06-tool-result-retention-library.i18n.yaml | 4 +- ...026-07-06-tool-result-retention-library.md | 8 +- ...-07-06-tool-result-retention-library.zh.md | 6 +- ...6-07-07-tool-call-timeout-policy.i18n.yaml | 4 +- .../2026-07-07-tool-call-timeout-policy.md | 20 +- .../2026-07-07-tool-call-timeout-policy.zh.md | 20 +- ...26-07-08-tool-output-spill-files.i18n.yaml | 4 +- .../2026-07-08-tool-output-spill-files.md | 12 +- .../2026-07-08-tool-output-spill-files.zh.md | 12 +- ...n-pressure-and-overflow-recovery.i18n.yaml | 4 +- ...mpaction-pressure-and-overflow-recovery.md | 16 +- ...ction-pressure-and-overflow-recovery.zh.md | 16 +- ...cutable-sdk-runtime-distribution.i18n.yaml | 4 +- ...ile-executable-sdk-runtime-distribution.md | 16 +- ...-executable-sdk-runtime-distribution.zh.md | 16 +- ...07-12-agent-scope-runtime-design.i18n.yaml | 4 +- .../2026-07-12-agent-scope-runtime-design.md | 10 +- ...026-07-12-agent-scope-runtime-design.zh.md | 10 +- .../2026-07-12-scoped-layers-store.i18n.yaml | 4 +- .../2026-07-12-scoped-layers-store.md | 10 +- .../2026-07-12-scoped-layers-store.zh.md | 10 +- ...-14-provider-routed-llm-adapters.i18n.yaml | 4 +- ...2026-07-14-provider-routed-llm-adapters.md | 8 +- ...6-07-14-provider-routed-llm-adapters.zh.md | 8 +- ...2026-07-15-agent-initiator-scope.i18n.yaml | 2 +- .../2026-07-15-agent-initiator-scope.md | 2 +- ...-model-catalog-and-acp-selection.i18n.yaml | 4 +- ...-15-llm-model-catalog-and-acp-selection.md | 8 +- ...-llm-model-catalog-and-acp-selection.zh.md | 8 +- .../2026-07-15-lsp-capability-seam.i18n.yaml | 4 +- .../2026-07-15-lsp-capability-seam.md | 14 +- .../2026-07-15-lsp-capability-seam.zh.md | 14 +- ...07-15-replay-token-meter-service.i18n.yaml | 4 +- .../2026-07-15-replay-token-meter-service.md | 16 +- ...026-07-15-replay-token-meter-service.zh.md | 18 +- ...19-gui-layering-and-rpc-protocol.i18n.yaml | 4 +- ...026-07-19-gui-layering-and-rpc-protocol.md | 8 +- ...-07-19-gui-layering-and-rpc-protocol.zh.md | 8 +- ...kage-invariant-runtime-contracts.i18n.yaml | 4 +- ...-19-package-invariant-runtime-contracts.md | 10 +- ...-package-invariant-runtime-contracts.zh.md | 10 +- ...0-canonical-tool-output-contract.i18n.yaml | 4 +- ...26-07-20-canonical-tool-output-contract.md | 10 +- ...07-20-canonical-tool-output-contract.zh.md | 6 +- ...el-context-and-compaction-policy.i18n.yaml | 4 +- ...ted-model-context-and-compaction-policy.md | 12 +- ...-model-context-and-compaction-policy.zh.md | 12 +- ...2-slot-type-chain-implementation.i18n.yaml | 4 +- ...26-07-22-slot-type-chain-implementation.md | 2 +- ...07-22-slot-type-chain-implementation.zh.md | 2 +- ...7-23-client-plugin-loading-model.i18n.yaml | 4 +- .../2026-07-23-client-plugin-loading-model.md | 8 +- ...26-07-23-client-plugin-loading-model.zh.md | 8 +- ...ed-reasoning-effort-capabilities.i18n.yaml | 4 +- ...ter-owned-reasoning-effort-capabilities.md | 4 +- ...-owned-reasoning-effort-capabilities.zh.md | 4 +- ...-24-single-harness-home-resolver.i18n.yaml | 4 +- ...2026-07-24-single-harness-home-resolver.md | 10 +- ...6-07-24-single-harness-home-resolver.zh.md | 10 +- ...tree-boot-and-transport-layering.i18n.yaml | 4 +- ...config-tree-boot-and-transport-layering.md | 2 +- ...fig-tree-boot-and-transport-layering.zh.md | 2 +- ...ession-scope-and-provide-channel.i18n.yaml | 4 +- ...lient-session-scope-and-provide-channel.md | 4 +- ...nt-session-scope-and-provide-channel.zh.md | 4 +- ...eb-command-surfaces-and-assembly.i18n.yaml | 4 +- ...07-25-web-command-surfaces-and-assembly.md | 10 +- ...25-web-command-surfaces-and-assembly.zh.md | 10 +- ...input-machine-and-slash-pipeline.i18n.yaml | 4 +- ...25-web-input-machine-and-slash-pipeline.md | 18 +- ...web-input-machine-and-slash-pipeline.zh.md | 18 +- ...=> 2026-07-26-job-registry-seam.i18n.yaml} | 6 +- .../2026-07-26-job-registry-seam.md | 35 + .../2026-07-26-job-registry-seam.zh.md | 35 + .../2026-07-26-subprocess-seam.i18n.yaml | 4 +- .../2026-07-26-subprocess-seam.md | 18 +- .../2026-07-26-subprocess-seam.zh.md | 16 +- .../2026-07-26-task-registry-seam.md | 35 - .../2026-07-26-task-registry-seam.zh.md | 35 - ...ompiler-independent-typert-model.i18n.yaml | 4 +- ...07-27-compiler-independent-typert-model.md | 2 +- ...27-compiler-independent-typert-model.zh.md | 2 +- ...rtable-execution-world-consumers.i18n.yaml | 4 +- ...7-28-portable-execution-world-consumers.md | 8 +- ...8-portable-execution-world-consumers.zh.md | 8 +- .../2026-07-28-user-settings-seam.i18n.yaml | 4 +- .../2026-07-28-user-settings-seam.md | 2 +- .../2026-07-28-user-settings-seam.zh.md | 2 +- ...-07-29-dsh-source-launch-tsx-esm.i18n.yaml | 4 +- .../2026-07-29-dsh-source-launch-tsx-esm.md | 2 +- ...2026-07-29-dsh-source-launch-tsx-esm.zh.md | 2 +- .../2026-07-29-package-regrouping.i18n.yaml | 4 +- .../2026-07-29-package-regrouping.md | 33 +- .../2026-07-29-package-regrouping.zh.md | 33 +- ...-token-usage-and-request-context.i18n.yaml | 4 +- ...ojected-token-usage-and-request-context.md | 2 +- ...cted-token-usage-and-request-context.zh.md | 2 +- ...est-level-llm-config-credentials.i18n.yaml | 4 +- ...29-request-level-llm-config-credentials.md | 2 +- ...request-level-llm-config-credentials.zh.md | 2 +- ...-29-terminal-llm-stream-failures.i18n.yaml | 4 +- ...2026-07-29-terminal-llm-stream-failures.md | 8 +- ...6-07-29-terminal-llm-stream-failures.zh.md | 8 +- ...adapter-owned-max-token-defaults.i18n.yaml | 4 +- ...-07-30-adapter-owned-max-token-defaults.md | 4 +- ...-30-adapter-owned-max-token-defaults.zh.md | 4 +- ...26-07-30-config-plane-boundaries.i18n.yaml | 4 +- .../2026-07-30-config-plane-boundaries.md | 2 +- .../2026-07-30-config-plane-boundaries.zh.md | 2 +- ...undaries-and-atomic-registration.i18n.yaml | 4 +- ...tial-boundaries-and-atomic-registration.md | 4 +- ...l-boundaries-and-atomic-registration.zh.md | 4 +- ...30-session-end-seed-log-boundary.i18n.yaml | 4 +- ...026-07-30-session-end-seed-log-boundary.md | 10 +- ...-07-30-session-end-seed-log-boundary.zh.md | 10 +- ...30-settings-write-path-integrity.i18n.yaml | 4 +- ...026-07-30-settings-write-path-integrity.md | 2 +- ...-07-30-settings-write-path-integrity.zh.md | 2 +- .../2026-07-30-web-config-plane.i18n.yaml | 4 +- .../2026-07-30-web-config-plane.md | 4 +- .../2026-07-30-web-config-plane.zh.md | 4 +- ...claimed-pre-step-inbox-lifecycle.i18n.yaml | 4 +- ...-07-31-claimed-pre-step-inbox-lifecycle.md | 2 +- ...-31-claimed-pre-step-inbox-lifecycle.zh.md | 2 +- ...runtime-portable-identifier-seam.i18n.yaml | 4 +- ...1-code-runtime-portable-identifier-seam.md | 2 +- ...ode-runtime-portable-identifier-seam.zh.md | 2 +- ...-07-31-goal-owned-durable-events.i18n.yaml | 4 +- .../2026-07-31-goal-owned-durable-events.md | 4 +- ...2026-07-31-goal-owned-durable-events.zh.md | 4 +- ...26-08-01-packaged-ripgrep-search.i18n.yaml | 4 +- .../2026-08-01-packaged-ripgrep-search.md | 2 +- .../2026-08-01-packaged-ripgrep-search.zh.md | 2 +- ...08-02-typert-remote-method-calls.i18n.yaml | 4 +- .../2026-08-02-typert-remote-method-calls.md | 116 +- ...026-08-02-typert-remote-method-calls.zh.md | 116 +- ...4-configuration-source-ownership.i18n.yaml | 4 +- ...26-08-04-configuration-source-ownership.md | 4 +- ...08-04-configuration-source-ownership.zh.md | 4 +- ...-a-provider-from-the-models-page.i18n.yaml | 4 +- ...claring-a-provider-from-the-models-page.md | 2 +- ...ring-a-provider-from-the-models-page.zh.md | 2 +- ...026-08-05-profile-plugin-bundles.i18n.yaml | 4 +- .../2026-08-05-profile-plugin-bundles.md | 2 +- .../2026-08-05-profile-plugin-bundles.zh.md | 2 +- ...08-05-slot-declaration-injection.i18n.yaml | 4 +- .../2026-08-05-slot-declaration-injection.md | 4 +- ...026-08-05-slot-declaration-injection.zh.md | 4 +- ...ubagent-list-identity-projection.i18n.yaml | 4 +- ...08-06-subagent-list-identity-projection.md | 2 +- ...06-subagent-list-identity-projection.zh.md | 2 +- ...hared-feedback-telemetry-user-id.i18n.yaml | 4 +- ...08-07-shared-feedback-telemetry-user-id.md | 4 +- ...07-shared-feedback-telemetry-user-id.zh.md | 4 +- ...08-08-per-preset-standing-mounts.i18n.yaml | 4 +- .../2026-08-08-per-preset-standing-mounts.md | 8 +- ...026-08-08-per-preset-standing-mounts.zh.md | 8 +- ...lient-conversation-node-assembly.i18n.yaml | 4 +- ...08-09-client-conversation-node-assembly.md | 2 +- ...09-client-conversation-node-assembly.zh.md | 2 +- ...headless-direct-core-entry-point.i18n.yaml | 4 +- ...-08-09-headless-direct-core-entry-point.md | 2 +- ...-09-headless-direct-core-entry-point.zh.md | 2 +- ...026-08-09-layered-skill-registry.i18n.yaml | 4 +- .../2026-08-09-layered-skill-registry.md | 4 +- .../2026-08-09-layered-skill-registry.zh.md | 4 +- ...8-10-fork-children-stay-one-shot.i18n.yaml | 4 +- .../2026-08-10-fork-children-stay-one-shot.md | 6 +- ...26-08-10-fork-children-stay-one-shot.zh.md | 6 +- ...st-plane-ownership-after-presets.i18n.yaml | 4 +- ...8-10-host-plane-ownership-after-presets.md | 4 +- ...0-host-plane-ownership-after-presets.zh.md | 4 +- ...6-08-10-message-feedback-sidecar.i18n.yaml | 4 +- .../2026-08-10-message-feedback-sidecar.md | 2 +- .../2026-08-10-message-feedback-sidecar.zh.md | 2 +- ...2026-08-10-remote-event-delivery.i18n.yaml | 4 +- .../2026-08-10-remote-event-delivery.md | 36 +- .../2026-08-10-remote-event-delivery.zh.md | 36 +- .../2026-08-11-plugin-settings-tabs.i18n.yaml | 4 +- .../2026-08-11-plugin-settings-tabs.md | 10 +- .../2026-08-11-plugin-settings-tabs.zh.md | 10 +- ...20-error-cause-chain-diagnostics.i18n.yaml | 4 +- ...026-07-20-error-cause-chain-diagnostics.md | 2 +- ...-07-20-error-cause-chain-diagnostics.zh.md | 2 +- ...ction-summary-prefix-cache-reuse.i18n.yaml | 4 +- ...1-compaction-summary-prefix-cache-reuse.md | 12 +- ...ompaction-summary-prefix-cache-reuse.zh.md | 12 +- ...mpty-model-response-is-retryable.i18n.yaml | 4 +- ...07-24-empty-model-response-is-retryable.md | 2 +- ...24-empty-model-response-is-retryable.zh.md | 2 +- ...2026-07-28-web-gui-feedback-loop.i18n.yaml | 2 +- .../2026-07-28-web-gui-feedback-loop.md | 2 +- ...9-human-transcript-append-origin.i18n.yaml | 4 +- ...26-07-29-human-transcript-append-origin.md | 12 +- ...07-29-human-transcript-append-origin.zh.md | 12 +- ...select-custom-answer-composition.i18n.yaml | 2 +- ...-multi-select-custom-answer-composition.md | 2 +- ...ranscript-log-ordered-projection.i18n.yaml | 4 +- ...0-web-transcript-log-ordered-projection.md | 16 +- ...eb-transcript-log-ordered-projection.zh.md | 16 +- ...-fork-anchor-floors-to-event-seq.i18n.yaml | 4 +- ...6-07-31-fork-anchor-floors-to-event-seq.md | 2 +- ...7-31-fork-anchor-floors-to-event-seq.zh.md | 2 +- ...same-basename-workspace-adoption.i18n.yaml | 4 +- ...-07-31-same-basename-workspace-adoption.md | 2 +- ...-31-same-basename-workspace-adoption.zh.md | 2 +- ...-ask-user-delegated-caller-guard.i18n.yaml | 4 +- ...6-08-01-ask-user-delegated-caller-guard.md | 6 +- ...8-01-ask-user-delegated-caller-guard.zh.md | 6 +- ...3-cli-signal-shutdown-escalation.i18n.yaml | 2 +- ...26-08-03-cli-signal-shutdown-escalation.md | 2 +- ...3-hmr-initial-scan-boot-deadlock.i18n.yaml | 2 +- ...26-08-03-hmr-initial-scan-boot-deadlock.md | 2 +- ...ontext-meter-blind-to-compaction.i18n.yaml | 4 +- ...08-05-context-meter-blind-to-compaction.md | 4 +- ...05-context-meter-blind-to-compaction.zh.md | 4 +- ...-08-06-api-key-format-validation.i18n.yaml | 4 +- .../2026-08-06-api-key-format-validation.md | 8 +- ...2026-08-06-api-key-format-validation.zh.md | 8 +- ...8-06-host-backed-web-preferences.i18n.yaml | 4 +- .../2026-08-06-host-backed-web-preferences.md | 2 +- ...26-08-06-host-backed-web-preferences.zh.md | 2 +- ...rding-step-owned-takeover-chrome.i18n.yaml | 4 +- ...6-onboarding-step-owned-takeover-chrome.md | 2 +- ...nboarding-step-owned-takeover-chrome.zh.md | 2 +- ...e-unpriced-replace-compatibility.i18n.yaml | 4 +- ...-surface-unpriced-replace-compatibility.md | 2 +- ...rface-unpriced-replace-compatibility.zh.md | 2 +- ...07-cancel-convergence-wake-latch.i18n.yaml | 2 +- ...026-08-07-cancel-convergence-wake-latch.md | 2 +- ...8-07-code-mode-executor-collapse.i18n.yaml | 4 +- .../2026-08-07-code-mode-executor-collapse.md | 4 +- ...26-08-07-code-mode-executor-collapse.zh.md | 4 +- ...9-filesystem-absence-observation.i18n.yaml | 4 +- ...26-08-09-filesystem-absence-observation.md | 4 +- ...08-09-filesystem-absence-observation.zh.md | 4 +- ...-agents-join-their-parent-preset.i18n.yaml | 4 +- ...0-child-agents-join-their-parent-preset.md | 6 +- ...hild-agents-join-their-parent-preset.zh.md | 6 +- ...08-10-pre-plugin-theme-bootstrap.i18n.yaml | 4 +- .../2026-08-10-pre-plugin-theme-bootstrap.md | 10 +- ...026-08-10-pre-plugin-theme-bootstrap.zh.md | 10 +- ...sh-catalog-follows-preset-switch.i18n.yaml | 4 +- ...-10-slash-catalog-follows-preset-switch.md | 10 +- ...-slash-catalog-follows-preset-switch.zh.md | 10 +- ...ounded-background-job-admission.i18n.yaml} | 6 +- ...08-11-bounded-background-job-admission.md} | 24 +- ...11-bounded-background-job-admission.zh.md} | 20 +- ...nt-validates-its-own-composition.i18n.yaml | 4 +- ...ing-agent-validates-its-own-composition.md | 8 +- ...-agent-validates-its-own-composition.zh.md | 8 +- ...chronous-subprocess-exit-cleanup.i18n.yaml | 4 +- ...-11-synchronous-subprocess-exit-cleanup.md | 2 +- ...-synchronous-subprocess-exit-cleanup.zh.md | 2 +- .../2026-06-14-acp-multi-session.i18n.yaml | 4 +- .../feature/2026-06-14-acp-multi-session.md | 10 +- .../2026-06-14-acp-multi-session.zh.md | 4 +- .../feature/2026-06-15-code-mode.i18n.yaml | 4 +- .../feature/2026-06-15-code-mode.md | 10 +- .../feature/2026-06-15-code-mode.zh.md | 10 +- ...26-06-17-filesystem-tool-schemas.i18n.yaml | 4 +- .../2026-06-17-filesystem-tool-schemas.md | 12 +- .../2026-06-17-filesystem-tool-schemas.zh.md | 12 +- ...06-18-compaction-capability-seam.i18n.yaml | 4 +- .../2026-06-18-compaction-capability-seam.md | 58 +- ...026-06-18-compaction-capability-seam.zh.md | 60 +- ...6-06-21-subagent-capability-seam.i18n.yaml | 4 +- .../2026-06-21-subagent-capability-seam.md | 16 +- .../2026-06-21-subagent-capability-seam.zh.md | 16 +- .../2026-06-24-workspace-context.i18n.yaml | 4 +- .../feature/2026-06-24-workspace-context.md | 10 +- .../2026-06-24-workspace-context.zh.md | 10 +- .../feature/2026-06-30-hook-bridges.i18n.yaml | 4 +- .../feature/2026-06-30-hook-bridges.md | 6 +- .../feature/2026-06-30-hook-bridges.zh.md | 6 +- .../2026-06-30-hook-protocol-lib.i18n.yaml | 4 +- .../feature/2026-06-30-hook-protocol-lib.md | 6 +- .../2026-06-30-hook-protocol-lib.zh.md | 6 +- ...30-interception-extension-points.i18n.yaml | 4 +- ...026-06-30-interception-extension-points.md | 4 +- ...-06-30-interception-extension-points.zh.md | 4 +- ...026-06-30-session-store-fork-api.i18n.yaml | 4 +- .../2026-06-30-session-store-fork-api.md | 4 +- .../2026-06-30-session-store-fork-api.zh.md | 4 +- .../2026-07-05-dynamic-workflows.i18n.yaml | 4 +- .../feature/2026-07-05-dynamic-workflows.md | 10 +- .../2026-07-05-dynamic-workflows.zh.md | 8 +- .../feature/2026-07-05-skill-system.i18n.yaml | 4 +- .../feature/2026-07-05-skill-system.md | 4 +- .../feature/2026-07-05-skill-system.zh.md | 4 +- .../2026-07-06-approval-seam.i18n.yaml | 4 +- .../feature/2026-07-06-approval-seam.md | 4 +- .../feature/2026-07-06-approval-seam.zh.md | 4 +- .../2026-07-06-explicit-tool-order.i18n.yaml | 4 +- .../feature/2026-07-06-explicit-tool-order.md | 4 +- .../2026-07-06-explicit-tool-order.zh.md | 4 +- .../feature/2026-07-06-sandbox.i18n.yaml | 4 +- .../implemented/feature/2026-07-06-sandbox.md | 26 +- .../feature/2026-07-06-sandbox.zh.md | 26 +- .../2026-07-07-mcp-client-plugin.i18n.yaml | 4 +- .../feature/2026-07-07-mcp-client-plugin.md | 6 +- .../2026-07-07-mcp-client-plugin.zh.md | 6 +- ...-07-08-background-subagent-tasks.i18n.yaml | 4 +- .../2026-07-08-background-subagent-tasks.md | 14 +- ...2026-07-08-background-subagent-tasks.zh.md | 8 +- ...-self-referential-cordis-toolset.i18n.yaml | 4 +- ...6-07-08-self-referential-cordis-toolset.md | 10 +- ...7-08-self-referential-cordis-toolset.zh.md | 10 +- ...ession-identity-and-log-location.i18n.yaml | 4 +- ...agent-session-identity-and-log-location.md | 8 +- ...nt-session-identity-and-log-location.zh.md | 8 +- ...-10-parallel-tool-call-execution.i18n.yaml | 4 +- ...2026-07-10-parallel-tool-call-execution.md | 2 +- ...6-07-10-parallel-tool-call-execution.zh.md | 2 +- ...nt-persona-tool-filter-and-depth.i18n.yaml | 4 +- ...-subagent-persona-tool-filter-and-depth.md | 6 +- ...bagent-persona-tool-filter-and-depth.zh.md | 6 +- ...26-07-14-cross-family-fs-sandbox.i18n.yaml | 4 +- .../2026-07-14-cross-family-fs-sandbox.md | 20 +- .../2026-07-14-cross-family-fs-sandbox.zh.md | 20 +- .../2026-07-16-harness-level-loop.i18n.yaml | 4 +- .../feature/2026-07-16-harness-level-loop.md | 10 +- .../2026-07-16-harness-level-loop.zh.md | 4 +- ...26-07-16-persistent-pty-sessions.i18n.yaml | 4 +- .../2026-07-16-persistent-pty-sessions.md | 42 +- .../2026-07-16-persistent-pty-sessions.zh.md | 42 +- ...-fresh-agent-ralph-workflow-tool.i18n.yaml | 4 +- ...6-07-19-fresh-agent-ralph-workflow-tool.md | 2 +- ...7-19-fresh-agent-ralph-workflow-tool.zh.md | 2 +- ...9-same-session-goal-round-driver.i18n.yaml | 4 +- ...26-07-19-same-session-goal-round-driver.md | 2 +- ...07-19-same-session-goal-round-driver.zh.md | 2 +- ...-20-code-mode-typed-tool-returns.i18n.yaml | 4 +- ...2026-07-20-code-mode-typed-tool-returns.md | 8 +- ...6-07-20-code-mode-typed-tool-returns.zh.md | 8 +- ...26-07-20-dsh-cli-personal-config.i18n.yaml | 4 +- .../2026-07-20-dsh-cli-personal-config.md | 4 +- .../2026-07-20-dsh-cli-personal-config.zh.md | 4 +- ...continuable-background-subagents.i18n.yaml | 4 +- ...-07-21-continuable-background-subagents.md | 46 +- ...-21-continuable-background-subagents.zh.md | 36 +- ...6-07-21-cross-session-references.i18n.yaml | 4 +- .../2026-07-21-cross-session-references.md | 6 +- .../2026-07-21-cross-session-references.zh.md | 6 +- ...7-21-follow-instruction-symlinks.i18n.yaml | 4 +- .../2026-07-21-follow-instruction-symlinks.md | 6 +- ...26-07-21-follow-instruction-symlinks.zh.md | 6 +- ...07-21-instruction-load-all-dedup.i18n.yaml | 4 +- .../2026-07-21-instruction-load-all-dedup.md | 2 +- ...026-07-21-instruction-load-all-dedup.zh.md | 2 +- ...-07-21-local-instruction-overlay.i18n.yaml | 4 +- .../2026-07-21-local-instruction-overlay.md | 2 +- ...2026-07-21-local-instruction-overlay.zh.md | 2 +- ...-07-21-log-backed-session-titles.i18n.yaml | 2 +- .../2026-07-21-log-backed-session-titles.md | 10 +- ...subagent-catalog-and-list-agents.i18n.yaml | 4 +- ...urable-subagent-catalog-and-list-agents.md | 14 +- ...ble-subagent-catalog-and-list-agents.zh.md | 14 +- ...ge-input-and-durable-attachments.i18n.yaml | 4 +- ...dal-image-input-and-durable-attachments.md | 8 +- ...-image-input-and-durable-attachments.zh.md | 8 +- ...3-session-telemetry-otel-revival.i18n.yaml | 4 +- ...26-07-23-session-telemetry-otel-revival.md | 6 +- ...07-23-session-telemetry-otel-revival.zh.md | 6 +- ...7-23-web-permission-and-approval.i18n.yaml | 4 +- .../2026-07-23-web-permission-and-approval.md | 10 +- ...26-07-23-web-permission-and-approval.zh.md | 10 +- .../2026-07-23-web-todo-display.i18n.yaml | 4 +- .../feature/2026-07-23-web-todo-display.md | 2 +- .../feature/2026-07-23-web-todo-display.zh.md | 2 +- ...07-24-web-session-model-selector.i18n.yaml | 4 +- .../2026-07-24-web-session-model-selector.md | 4 +- ...026-07-24-web-session-model-selector.zh.md | 4 +- ...-07-25-workspace-ui-product-flow.i18n.yaml | 4 +- .../2026-07-25-workspace-ui-product-flow.md | 2 +- ...2026-07-25-workspace-ui-product-flow.zh.md | 2 +- ...7-26-code-dispatch-ui-foundation.i18n.yaml | 2 +- .../2026-07-26-code-dispatch-ui-foundation.md | 2 +- ...ative-workspace-directory-picker.i18n.yaml | 4 +- ...07-27-native-workspace-directory-picker.md | 2 +- ...27-native-workspace-directory-picker.zh.md | 2 +- ...-07-27-skill-catalog-hot-refresh.i18n.yaml | 4 +- .../2026-07-27-skill-catalog-hot-refresh.md | 2 +- ...2026-07-27-skill-catalog-hot-refresh.zh.md | 2 +- ...2026-07-27-tmux-location-context.i18n.yaml | 4 +- .../2026-07-27-tmux-location-context.md | 6 +- .../2026-07-27-tmux-location-context.zh.md | 6 +- ...ipt-sdk-and-sdk-subagent-backend.i18n.yaml | 4 +- ...typescript-sdk-and-sdk-subagent-backend.md | 8 +- ...escript-sdk-and-sdk-subagent-backend.zh.md | 8 +- .../2026-07-27-web-session-search.i18n.yaml | 4 +- .../feature/2026-07-27-web-session-search.md | 2 +- .../2026-07-27-web-session-search.zh.md | 2 +- ...07-27-web-subagent-conversations.i18n.yaml | 4 +- .../2026-07-27-web-subagent-conversations.md | 4 +- ...026-07-27-web-subagent-conversations.zh.md | 4 +- ...-workspace-registration-deletion.i18n.yaml | 4 +- ...6-07-27-workspace-registration-deletion.md | 2 +- ...7-27-workspace-registration-deletion.zh.md | 2 +- ...ntinuable-subagent-conversations.i18n.yaml | 4 +- ...7-28-continuable-subagent-conversations.md | 10 +- ...8-continuable-subagent-conversations.zh.md | 4 +- .../2026-07-28-feedback-command.i18n.yaml | 4 +- .../feature/2026-07-28-feedback-command.md | 4 +- .../feature/2026-07-28-feedback-command.zh.md | 4 +- ...2026-07-28-sdk-max-output-tokens.i18n.yaml | 4 +- .../2026-07-28-sdk-max-output-tokens.md | 4 +- .../2026-07-28-sdk-max-output-tokens.zh.md | 4 +- ...-07-28-tool-call-file-open-in-os.i18n.yaml | 4 +- .../2026-07-28-tool-call-file-open-in-os.md | 2 +- ...2026-07-28-tool-call-file-open-in-os.zh.md | 2 +- ...29-ask-question-web-presentation.i18n.yaml | 4 +- ...026-07-29-ask-question-web-presentation.md | 4 +- ...-07-29-ask-question-web-presentation.zh.md | 4 +- ...rsistent-bash-str-replace-editor.i18n.yaml | 4 +- ...7-29-persistent-bash-str-replace-editor.md | 2 +- ...9-persistent-bash-str-replace-editor.zh.md | 2 +- ...continuable-subagent-report-tool.i18n.yaml | 2 +- ...-07-30-continuable-subagent-report-tool.md | 2 +- ...seek-onboarding-credential-setup.i18n.yaml | 4 +- ...30-deepseek-onboarding-credential-setup.md | 4 +- ...deepseek-onboarding-credential-setup.zh.md | 4 +- ...-plan-review-presentation-intent.i18n.yaml | 4 +- ...6-07-30-plan-review-presentation-intent.md | 12 +- ...7-30-plan-review-presentation-intent.zh.md | 12 +- ...6-07-30-queued-manual-compaction.i18n.yaml | 4 +- .../2026-07-30-queued-manual-compaction.md | 28 +- .../2026-07-30-queued-manual-compaction.zh.md | 28 +- ...versioned-gui-welcome-onboarding.i18n.yaml | 4 +- ...-07-30-versioned-gui-welcome-onboarding.md | 2 +- ...-30-versioned-gui-welcome-onboarding.zh.md | 2 +- .../2026-07-30-web-read-card.i18n.yaml | 4 +- .../feature/2026-07-30-web-read-card.md | 2 +- .../feature/2026-07-30-web-read-card.zh.md | 2 +- ...1-browser-derived-initial-locale.i18n.yaml | 4 +- ...26-07-31-browser-derived-initial-locale.md | 4 +- ...07-31-browser-derived-initial-locale.zh.md | 4 +- ...7-31-code-mode-language-dispatch.i18n.yaml | 4 +- .../2026-07-31-code-mode-language-dispatch.md | 6 +- ...26-07-31-code-mode-language-dispatch.zh.md | 6 +- ...31-even-out-shipped-tool-rosters.i18n.yaml | 4 +- ...026-07-31-even-out-shipped-tool-rosters.md | 10 +- ...-07-31-even-out-shipped-tool-rosters.zh.md | 10 +- ...-31-gui-full-access-confirmation.i18n.yaml | 4 +- ...2026-07-31-gui-full-access-confirmation.md | 2 +- ...6-07-31-gui-full-access-confirmation.zh.md | 2 +- ...mission-default-for-new-sessions.i18n.yaml | 4 +- ...-31-permission-default-for-new-sessions.md | 4 +- ...-permission-default-for-new-sessions.zh.md | 4 +- ...07-31-session-archive-global-set.i18n.yaml | 4 +- .../2026-07-31-session-archive-global-set.md | 2 +- ...026-07-31-session-archive-global-set.zh.md | 2 +- ...7-31-telemetry-anonymous-user-id.i18n.yaml | 4 +- .../2026-07-31-telemetry-anonymous-user-id.md | 18 +- ...26-07-31-telemetry-anonymous-user-id.zh.md | 16 +- .../2026-07-31-web-default-search.i18n.yaml | 4 +- .../feature/2026-07-31-web-default-search.md | 6 +- .../2026-07-31-web-default-search.zh.md | 4 +- ...7-31-web-telemetry-default-mount.i18n.yaml | 4 +- .../2026-07-31-web-telemetry-default-mount.md | 4 +- ...26-07-31-web-telemetry-default-mount.zh.md | 4 +- ...-workspace-write-surface-default.i18n.yaml | 4 +- ...6-07-31-workspace-write-surface-default.md | 2 +- ...7-31-workspace-write-surface-default.zh.md | 2 +- ...026-08-01-pwsh-tool-and-executor.i18n.yaml | 4 +- .../2026-08-01-pwsh-tool-and-executor.md | 10 +- .../2026-08-01-pwsh-tool-and-executor.zh.md | 8 +- .../2026-08-01-windows-pwsh-default.i18n.yaml | 4 +- .../2026-08-01-windows-pwsh-default.md | 6 +- .../2026-08-01-windows-pwsh-default.zh.md | 6 +- ...2026-08-02-pwsh-tool-bash-parity.i18n.yaml | 4 +- .../2026-08-02-pwsh-tool-bash-parity.md | 12 +- .../2026-08-02-pwsh-tool-bash-parity.zh.md | 12 +- .../2026-08-03-fs-tool-error-remedy.i18n.yaml | 4 +- .../2026-08-03-fs-tool-error-remedy.md | 2 +- .../2026-08-03-fs-tool-error-remedy.zh.md | 2 +- ...b-context-source-and-steer-marks.i18n.yaml | 4 +- ...8-04-web-context-source-and-steer-marks.md | 2 +- ...4-web-context-source-and-steer-marks.zh.md | 2 +- ...26-08-05-context-form-vocabulary.i18n.yaml | 4 +- .../2026-08-05-context-form-vocabulary.md | 6 +- .../2026-08-05-context-form-vocabulary.zh.md | 6 +- .../2026-08-05-durable-web-schedule.i18n.yaml | 4 +- .../2026-08-05-durable-web-schedule.md | 4 +- .../2026-08-05-durable-web-schedule.zh.md | 4 +- ...feedback-gated-session-telemetry.i18n.yaml | 4 +- ...-08-05-feedback-gated-session-telemetry.md | 2 +- ...-05-feedback-gated-session-telemetry.zh.md | 2 +- ...8-05-per-agent-tool-presentation.i18n.yaml | 4 +- .../2026-08-05-per-agent-tool-presentation.md | 6 +- ...26-08-05-per-agent-tool-presentation.zh.md | 6 +- .../2026-08-05-pwsh-ui-bash-parity.i18n.yaml | 4 +- .../feature/2026-08-05-pwsh-ui-bash-parity.md | 10 +- .../2026-08-05-pwsh-ui-bash-parity.zh.md | 8 +- ...26-08-06-bundled-dsh-badge-skill.i18n.yaml | 4 +- .../2026-08-06-bundled-dsh-badge-skill.md | 2 +- .../2026-08-06-bundled-dsh-badge-skill.zh.md | 2 +- ...6-continuable-subagent-interrupt.i18n.yaml | 4 +- ...26-08-06-continuable-subagent-interrupt.md | 4 +- ...08-06-continuable-subagent-interrupt.zh.md | 4 +- ...ned-subagent-settlement-delivery.i18n.yaml | 4 +- ...ager-owned-subagent-settlement-delivery.md | 4 +- ...r-owned-subagent-settlement-delivery.zh.md | 4 +- .../2026-08-06-web-install-manifest.i18n.yaml | 4 +- .../2026-08-06-web-install-manifest.md | 4 +- .../2026-08-06-web-install-manifest.zh.md | 4 +- ...default-model-follows-the-picker.i18n.yaml | 4 +- ...-08-07-default-model-follows-the-picker.md | 4 +- ...-07-default-model-follows-the-picker.zh.md | 4 +- ...knowledgement-sharing-disclosure.i18n.yaml | 4 +- ...back-acknowledgement-sharing-disclosure.md | 4 +- ...k-acknowledgement-sharing-disclosure.zh.md | 4 +- ...8-user-explicit-skill-invocation.i18n.yaml | 4 +- ...26-08-08-user-explicit-skill-invocation.md | 2 +- ...08-08-user-explicit-skill-invocation.zh.md | 2 +- ...8-08-web-background-job-display.i18n.yaml} | 6 +- .../2026-08-08-web-background-job-display.md | 136 ++ ...026-08-08-web-background-job-display.zh.md | 136 ++ .../2026-08-08-web-background-task-display.md | 136 -- ...26-08-08-web-background-task-display.zh.md | 136 -- ...ows-acl-restricted-token-sandbox.i18n.yaml | 4 +- ...08-windows-acl-restricted-token-sandbox.md | 2 +- ...windows-acl-restricted-token-sandbox.zh.md | 2 +- ...09-parallel-subagent-delegations.i18n.yaml | 4 +- ...026-08-09-parallel-subagent-delegations.md | 4 +- ...-08-09-parallel-subagent-delegations.zh.md | 4 +- ...able-subagent-policy-inheritance.i18n.yaml | 4 +- ...continuable-subagent-policy-inheritance.md | 2 +- ...tinuable-subagent-policy-inheritance.zh.md | 2 +- ...2026-08-10-telemetry-default-off.i18n.yaml | 2 +- .../2026-08-10-telemetry-default-off.md | 2 +- ...6-08-10-web-plugin-configuration.i18n.yaml | 4 +- .../2026-08-10-web-plugin-configuration.md | 4 +- .../2026-08-10-web-plugin-configuration.zh.md | 4 +- ...und-first-continuable-delegation.i18n.yaml | 2 +- ...background-first-continuable-delegation.md | 2 +- ...-completion-wakes-an-idle-owner.i18n.yaml} | 6 +- ...und-job-completion-wakes-an-idle-owner.md} | 30 +- ...-job-completion-wakes-an-idle-owner.zh.md} | 24 +- ...-deepseek-request-user-id-header.i18n.yaml | 4 +- ...6-08-11-deepseek-request-user-id-header.md | 10 +- ...8-11-deepseek-request-user-id-header.zh.md | 8 +- ...-11-message-feedback-web-surface.i18n.yaml | 4 +- ...2026-08-11-message-feedback-web-surface.md | 4 +- ...6-08-11-message-feedback-web-surface.zh.md | 4 +- ...l-profiles-bare-two-tool-runtime.i18n.yaml | 4 +- ...-minimal-profiles-bare-two-tool-runtime.md | 4 +- ...nimal-profiles-bare-two-tool-runtime.zh.md | 4 +- ...11-web-export-command-and-dialog.i18n.yaml | 4 +- ...026-08-11-web-export-command-and-dialog.md | 2 +- ...-08-11-web-export-command-and-dialog.zh.md | 2 +- .../2026-06-17-ts-build-config.i18n.yaml | 4 +- .../process/2026-06-17-ts-build-config.md | 4 +- .../process/2026-06-17-ts-build-config.zh.md | 4 +- ...-20-core-data-structures-catalog.i18n.yaml | 4 +- ...2026-06-20-core-data-structures-catalog.md | 6 +- ...6-06-20-core-data-structures-catalog.zh.md | 6 +- .../2026-07-02-tool-schema-catalog.i18n.yaml | 4 +- .../process/2026-07-02-tool-schema-catalog.md | 4 +- .../2026-07-02-tool-schema-catalog.zh.md | 4 +- ...rial-cross-platform-ci-reference.i18n.yaml | 4 +- ...7-21-serial-cross-platform-ci-reference.md | 4 +- ...1-serial-cross-platform-ci-reference.zh.md | 4 +- .../2026-07-22-fast-local-git-hooks.i18n.yaml | 4 +- .../2026-07-22-fast-local-git-hooks.md | 2 +- .../2026-07-22-fast-local-git-hooks.zh.md | 2 +- ...subsystem-cordis-surface-regions.i18n.yaml | 4 +- ...28-per-subsystem-cordis-surface-regions.md | 6 +- ...per-subsystem-cordis-surface-regions.zh.md | 6 +- ...30-generated-third-party-notices.i18n.yaml | 4 +- ...026-07-30-generated-third-party-notices.md | 2 +- ...-07-30-generated-third-party-notices.zh.md | 2 +- ...remotes-generated-contract-build.i18n.yaml | 4 +- ...08-api-remotes-generated-contract-build.md | 12 +- ...api-remotes-generated-contract-build.zh.md | 12 +- ...08-unified-github-label-taxonomy.i18n.yaml | 2 +- ...026-08-08-unified-github-label-taxonomy.md | 2 +- ...2026-08-10-npm-release-sequences.i18n.yaml | 4 +- .../2026-08-10-npm-release-sequences.md | 4 +- .../2026-08-10-npm-release-sequences.zh.md | 4 +- .../2026-06-26-fsspec-style-fs-seam.i18n.yaml | 4 +- .../2026-06-26-fsspec-style-fs-seam.md | 22 +- .../2026-06-26-fsspec-style-fs-seam.zh.md | 22 +- ...4-tighten-hook-protocol-contract.i18n.yaml | 4 +- ...26-07-04-tighten-hook-protocol-contract.md | 4 +- ...07-04-tighten-hook-protocol-contract.zh.md | 4 +- ...-20-remove-stdio-and-echo-agents.i18n.yaml | 4 +- ...2026-07-20-remove-stdio-and-echo-agents.md | 2 +- ...6-07-20-remove-stdio-and-echo-agents.zh.md | 2 +- ...nwrap-injected-content-envelopes.i18n.yaml | 4 +- ...07-20-unwrap-injected-content-envelopes.md | 8 +- ...20-unwrap-injected-content-envelopes.zh.md | 8 +- ...lan-specific-collaboration-state.i18n.yaml | 2 +- ...07-22-plan-specific-collaboration-state.md | 6 +- ...-23-acp-automation-only-protocol.i18n.yaml | 2 +- ...2026-07-23-acp-automation-only-protocol.md | 4 +- ...6-merge-subagent-control-service.i18n.yaml | 4 +- ...26-07-26-merge-subagent-control-service.md | 10 +- ...07-26-merge-subagent-control-service.zh.md | 4 +- ...subagent-continuation-operations.i18n.yaml | 4 +- ...-named-subagent-continuation-operations.md | 4 +- ...med-subagent-continuation-operations.zh.md | 4 +- ...07-27-request-error-retry-action.i18n.yaml | 4 +- .../2026-07-27-request-error-retry-action.md | 2 +- ...026-07-27-request-error-retry-action.zh.md | 2 +- ...-remove-synthetic-log-only-turns.i18n.yaml | 4 +- ...6-07-28-remove-synthetic-log-only-turns.md | 2 +- ...7-28-remove-synthetic-log-only-turns.zh.md | 2 +- ...7-29-shared-base-config-overlays.i18n.yaml | 4 +- .../2026-07-29-shared-base-config-overlays.md | 4 +- ...26-07-29-shared-base-config-overlays.zh.md | 4 +- ...-31-one-route-to-add-a-workspace.i18n.yaml | 4 +- ...2026-07-31-one-route-to-add-a-workspace.md | 2 +- ...6-07-31-one-route-to-add-a-workspace.zh.md | 2 +- .../2026-08-04-remove-tui-package.i18n.yaml | 4 +- .../2026-08-04-remove-tui-package.md | 4 +- .../2026-08-04-remove-tui-package.zh.md | 2 +- ...6-buffer-free-feedback-telemetry.i18n.yaml | 4 +- ...26-08-06-buffer-free-feedback-telemetry.md | 2 +- ...08-06-buffer-free-feedback-telemetry.zh.md | 2 +- ...conversational-schedule-delivery.i18n.yaml | 4 +- ...-08-09-conversational-schedule-delivery.md | 2 +- ...-09-conversational-schedule-delivery.zh.md | 2 +- ...6-08-09-remove-repository-plugin.i18n.yaml | 4 +- .../2026-08-09-remove-repository-plugin.md | 4 +- .../2026-08-09-remove-repository-plugin.zh.md | 4 +- ...-11-remove-sdk-project-toolchain.i18n.yaml | 4 +- ...2026-08-11-remove-sdk-project-toolchain.md | 4 +- ...6-08-11-remove-sdk-project-toolchain.zh.md | 4 +- ...eparate-source-launch-from-build.i18n.yaml | 4 +- ...08-12-separate-source-launch-from-build.md | 2 +- ...12-separate-source-launch-from-build.zh.md | 2 +- .../2026-06-19-acp-snapshot-tests.i18n.yaml | 4 +- .../testing/2026-06-19-acp-snapshot-tests.md | 2 +- .../2026-06-19-acp-snapshot-tests.zh.md | 2 +- ...-fork-child-replay-seed-boundary.i18n.yaml | 4 +- ...6-06-22-fork-child-replay-seed-boundary.md | 4 +- ...6-22-fork-child-replay-seed-boundary.zh.md | 4 +- ...6-06-22-subagent-snapshot-replay.i18n.yaml | 4 +- .../2026-06-22-subagent-snapshot-replay.md | 4 +- .../2026-06-22-subagent-snapshot-replay.zh.md | 4 +- ...6-07-24-web-gui-browser-e2e-lane.i18n.yaml | 4 +- .../2026-07-24-web-gui-browser-e2e-lane.md | 10 +- .../2026-07-24-web-gui-browser-e2e-lane.zh.md | 10 +- .../2026-06-16-typed-event-schemas.i18n.yaml | 4 +- .../2026-06-16-typed-event-schemas.md | 2 +- .../2026-06-16-typed-event-schemas.zh.md | 2 +- ...on-through-tool-capability-seams.i18n.yaml | 2 +- ...cellation-through-tool-capability-seams.md | 2 +- ...-domain-kv-storage-and-workspace.i18n.yaml | 4 +- ...6-07-24-domain-kv-storage-and-workspace.md | 12 +- ...7-24-domain-kv-storage-and-workspace.zh.md | 12 +- ...-25-client-settings-locale-theme.i18n.yaml | 4 +- ...2026-07-25-client-settings-locale-theme.md | 12 +- ...6-07-25-client-settings-locale-theme.zh.md | 12 +- ...ssion-projection-and-command-log.i18n.yaml | 4 +- ...7-27-session-projection-and-command-log.md | 2 +- ...7-session-projection-and-command-log.zh.md | 2 +- ...root-and-derived-medium-recovery.i18n.yaml | 4 +- ...torage-root-and-derived-medium-recovery.md | 2 +- ...age-root-and-derived-medium-recovery.zh.md | 2 +- ...-unary-apiproxy-remote-migration.i18n.yaml | 4 +- ...6-08-10-unary-apiproxy-remote-migration.md | 26 +- ...8-10-unary-apiproxy-remote-migration.zh.md | 26 +- ...aming-contract-and-rename-ledger.i18n.yaml | 4 +- ...itory-naming-contract-and-rename-ledger.md | 34 +- ...ry-naming-contract-and-rename-ledger.zh.md | 34 +- ...2026-07-06-recallable-compaction.i18n.yaml | 4 +- .../2026-07-06-recallable-compaction.md | 18 +- .../2026-07-06-recallable-compaction.zh.md | 18 +- .../feature/2026-08-04-task-surface.i18n.yaml | 2 +- .../feature/2026-08-04-task-surface.md | 2 +- ...-07-04-prune-dead-core-spine-api.i18n.yaml | 4 +- .../2026-07-04-prune-dead-core-spine-api.md | 12 +- ...2026-07-04-prune-dead-core-spine-api.zh.md | 12 +- ...6-07-19-make-jsonrpc-directional.i18n.yaml | 4 +- .../2026-07-19-make-jsonrpc-directional.md | 2 +- .../2026-07-19-make-jsonrpc-directional.zh.md | 2 +- ...-20-drop-bash-output-spill-files.i18n.yaml | 2 +- ...2026-06-20-drop-bash-output-spill-files.md | 4 +- ...-prune-unused-skill-registry-api.i18n.yaml | 4 +- ...6-07-12-prune-unused-skill-registry-api.md | 2 +- ...7-12-prune-unused-skill-registry-api.zh.md | 2 +- ...19-fold-compaction-package-split.i18n.yaml | 4 +- ...026-07-19-fold-compaction-package-split.md | 12 +- ...-07-19-fold-compaction-package-split.zh.md | 12 +- ...-promises-for-hand-rolled-sleeps.i18n.yaml | 4 +- ...n-timer-promises-for-hand-rolled-sleeps.md | 12 +- ...imer-promises-for-hand-rolled-sleeps.zh.md | 12 +- ...ency-swaps-rejected-by-nih-audit.i18n.yaml | 4 +- ...-dependency-swaps-rejected-by-nih-audit.md | 10 +- ...pendency-swaps-rejected-by-nih-audit.zh.md | 10 +- .../skills/dsh-find-simplifications/SKILL.md | 4 +- .../dsh-prose-standard/references/examples.md | 2 +- .github/workflows/ci.yml | 8 +- .github/workflows/sandbox.yml | 2 +- AGENTS.md | 13 +- README.i18n.yaml | 4 +- README.md | 2 +- README.zh.md | 2 +- apps/cli/README.i18n.yaml | 4 +- apps/cli/README.md | 2 +- apps/cli/README.zh.md | 2 +- apps/cli/composition.md | 106 +- .../agent-presets/code/agent.cordis.yml | 48 +- .../agent-presets/cordis/agent.cordis.yml | 40 +- .../editing-cordis-compositions/SKILL.md | 6 +- .../agent-presets/minimal/agent.cordis.yml | 8 +- .../agent-presets/standard/agent.cordis.yml | 42 +- apps/cli/package.json | 30 +- apps/cli/reference/README.i18n.yaml | 4 +- apps/cli/reference/README.md | 2 +- apps/cli/reference/README.zh.md | 2 +- apps/cli/src/profile-boot.ts | 10 +- apps/cli/tests/fixtures/dsh-badge/cordis.yml | 4 +- .../fixtures/dsh-badge/default.cordis.yml | 4 +- apps/cli/tests/fixtures/dsh-badge/snapshot.ts | 2 +- apps/cli/tests/memory-mcp-configs.spec.ts | 4 +- apps/cli/tests/telemetry-switch.spec.ts | 2 +- apps/cli/tests/web-agent-presets.e2e.ts | 19 +- apps/cli/tsconfig.json | 10 +- apps/web/package.json | 2 +- apps/web/tests/agent-preset-selection.e2e.ts | 2 +- apps/web/tests/assembled-boot.ts | 2 +- ...list.e2e.ts => background-job-list.e2e.ts} | 40 +- apps/web/tests/chat-scroll-contract.e2e.ts | 2 +- apps/web/tests/goal-multi-turn-actions.e2e.ts | 10 +- apps/web/tests/hmr-live.e2e.ts | 4 +- apps/web/tests/lifecycle-chrome.e2e.ts | 2 +- apps/web/tests/minimal-preset.snapshot.ts | 2 +- apps/web/tests/pin-browse-picker.overlay.yml | 4 +- apps/web/tests/pwsh-terminal.overlay.yml | 2 +- apps/web/tests/question-composer.e2e.ts | 2 +- apps/web/tests/scaffold.ts | 30 +- apps/web/tests/schedule-after.e2e.ts | 8 +- apps/web/tests/seeded-history.e2e.ts | 20 +- apps/web/tests/settings-chrome.e2e.ts | 2 +- apps/web/tests/shipped-composition.e2e.ts | 24 +- .../tests/sidebar-subagent-activity.e2e.ts | 6 +- apps/web/tests/smoke-real.e2e.ts | 4 +- .../running.expected.md | 2 +- .../settled.expected.md | 2 +- .../feedback-command/ack.expected.md | 4 +- .../system-prompt.expected.md | 4 +- .../replay.override.json | 4 +- .../goal-multi-turn-actions/session.jsonl | 12 +- .../goal-multi-turn-actions/ui.expected.md | 4 +- .../permission-policy-context/session.jsonl | 2 +- .../seeded-history/feedback-row.expected.md | 6 +- .../owner-running.expected.md | 2 +- .../web-surface-prompt.expected.md | 2 +- apps/web/tests/startup-auto-selection.e2e.ts | 2 +- apps/web/tests/workspace-management.e2e.ts | 32 +- apps/web/tsconfig.json | 2 +- docs/agent-lifecycle.i18n.yaml | 4 +- docs/agent-lifecycle.md | 2 +- docs/agent-lifecycle.zh.md | 2 +- docs/api-gateway.i18n.yaml | 4 +- docs/api-gateway.md | 34 +- docs/api-gateway.zh.md | 34 +- docs/architecture.i18n.yaml | 4 +- docs/architecture.md | 6 +- docs/architecture.zh.md | 6 +- docs/capability-seams.i18n.yaml | 4 +- docs/capability-seams.md | 264 +-- docs/capability-seams.zh.md | 284 +-- docs/config-catalog.i18n.yaml | 4 +- docs/config-catalog.md | 553 +++--- docs/config-catalog.zh.md | 529 +++--- docs/cookbook/adding-a-package.i18n.yaml | 4 +- docs/cookbook/adding-a-package.md | 30 +- docs/cookbook/adding-a-package.zh.md | 30 +- docs/cookbook/adding-a-tool.i18n.yaml | 4 +- docs/cookbook/adding-a-tool.md | 6 +- docs/cookbook/adding-a-tool.zh.md | 6 +- docs/cookbook/adding-an-llm-adapter.i18n.yaml | 4 +- docs/cookbook/adding-an-llm-adapter.md | 2 +- docs/cookbook/adding-an-llm-adapter.zh.md | 2 +- docs/cookbook/extension-cookbook.i18n.yaml | 4 +- docs/cookbook/extension-cookbook.md | 14 +- docs/cookbook/extension-cookbook.zh.md | 12 +- docs/cordis-primer.i18n.yaml | 4 +- docs/cordis-primer.md | 2 +- docs/cordis-primer.zh.md | 2 +- docs/cordis-tutorial/index.i18n.yaml | 4 +- docs/cordis-tutorial/index.md | 2 +- docs/cordis-tutorial/index.zh.md | 2 +- docs/defensive-patterns.i18n.yaml | 4 +- docs/defensive-patterns.md | 4 +- docs/defensive-patterns.zh.md | 2 +- docs/development.i18n.yaml | 4 +- docs/development.md | 8 +- docs/development.zh.md | 8 +- docs/event-producer-consumer.i18n.yaml | 4 +- docs/event-producer-consumer.md | 54 +- docs/event-producer-consumer.zh.md | 54 +- docs/glossary.i18n.yaml | 4 +- docs/glossary.md | 6 +- docs/glossary.zh.md | 6 +- docs/i18n/style-samples.md | 2 +- docs/i18n/terminology.md | 20 +- docs/module-graph.i18n.yaml | 4 +- docs/module-graph.md | 1390 +++++++------- docs/module-graph.zh.md | 1390 +++++++------- docs/persistence-catalog.i18n.yaml | 4 +- docs/persistence-catalog.md | 44 +- docs/persistence-catalog.zh.md | 44 +- ...0003-web-agent-gui-feedback-loop.i18n.yaml | 2 +- .../0003-web-agent-gui-feedback-loop.md | 2 +- ...ice-misclassified-child-failures.i18n.yaml | 4 +- ...ial-notice-misclassified-child-failures.md | 4 +- ...-notice-misclassified-child-failures.zh.md | 4 +- docs/subsystems/README.i18n.yaml | 4 +- docs/subsystems/README.md | 18 +- docs/subsystems/README.zh.md | 18 +- docs/subsystems/approval.i18n.yaml | 4 +- docs/subsystems/approval.md | 2 +- docs/subsystems/approval.zh.md | 2 +- docs/subsystems/client-modules.i18n.yaml | 4 +- docs/subsystems/client-modules.md | 8 +- docs/subsystems/client-modules.zh.md | 8 +- docs/subsystems/code-runtime.i18n.yaml | 4 +- docs/subsystems/code-runtime.md | 2 +- docs/subsystems/code-runtime.zh.md | 2 +- docs/subsystems/commands.i18n.yaml | 4 +- docs/subsystems/commands.md | 4 +- docs/subsystems/commands.zh.md | 4 +- docs/subsystems/compaction.i18n.yaml | 4 +- docs/subsystems/compaction.md | 52 +- docs/subsystems/compaction.zh.md | 52 +- docs/subsystems/core.i18n.yaml | 4 +- docs/subsystems/core.md | 6 +- docs/subsystems/core.zh.md | 6 +- docs/subsystems/credentials.i18n.yaml | 4 +- docs/subsystems/credentials.md | 8 +- docs/subsystems/credentials.zh.md | 8 +- docs/subsystems/feedback.i18n.yaml | 4 +- docs/subsystems/feedback.md | 6 +- docs/subsystems/feedback.zh.md | 6 +- docs/subsystems/filesystem.i18n.yaml | 4 +- docs/subsystems/filesystem.md | 20 +- docs/subsystems/filesystem.zh.md | 20 +- docs/subsystems/invariants.i18n.yaml | 4 +- docs/subsystems/invariants.md | 14 +- docs/subsystems/invariants.zh.md | 14 +- .../{pty.i18n.yaml => jobs.i18n.yaml} | 6 +- docs/subsystems/{tasks.md => jobs.md} | 146 +- docs/subsystems/{tasks.zh.md => jobs.zh.md} | 146 +- docs/subsystems/llm-streaming.i18n.yaml | 4 +- docs/subsystems/llm-streaming.md | 22 +- docs/subsystems/llm-streaming.zh.md | 22 +- docs/subsystems/lsp.i18n.yaml | 4 +- docs/subsystems/lsp.md | 2 +- docs/subsystems/lsp.zh.md | 2 +- docs/subsystems/permission-presets.i18n.yaml | 6 + .../{permission.md => permission-presets.md} | 20 +- ...mission.zh.md => permission-presets.zh.md} | 20 +- docs/subsystems/plan.i18n.yaml | 4 +- docs/subsystems/plan.md | 10 +- docs/subsystems/plan.zh.md | 10 +- docs/subsystems/sandbox.i18n.yaml | 4 +- docs/subsystems/sandbox.md | 4 +- docs/subsystems/sandbox.zh.md | 4 +- docs/subsystems/schedule.i18n.yaml | 4 +- docs/subsystems/schedule.md | 4 +- docs/subsystems/schedule.zh.md | 4 +- docs/subsystems/session-query.i18n.yaml | 4 +- docs/subsystems/session-query.md | 4 +- docs/subsystems/session-query.zh.md | 4 +- docs/subsystems/session-reference.i18n.yaml | 4 +- docs/subsystems/session-reference.md | 4 +- docs/subsystems/session-reference.zh.md | 4 +- docs/subsystems/session-telemetry.i18n.yaml | 6 + .../{telemetry.md => session-telemetry.md} | 60 +- ...elemetry.zh.md => session-telemetry.zh.md} | 58 +- docs/subsystems/session-title.i18n.yaml | 4 +- docs/subsystems/session-title.md | 2 +- docs/subsystems/session-title.zh.md | 2 +- docs/subsystems/session.i18n.yaml | 4 +- docs/subsystems/session.md | 14 +- docs/subsystems/session.zh.md | 14 +- docs/subsystems/settings.i18n.yaml | 4 +- docs/subsystems/settings.md | 8 +- docs/subsystems/settings.zh.md | 8 +- .../{bash.i18n.yaml => shell.i18n.yaml} | 6 +- docs/subsystems/{bash.md => shell.md} | 90 +- docs/subsystems/{bash.zh.md => shell.zh.md} | 86 +- docs/subsystems/skills.i18n.yaml | 4 +- docs/subsystems/skills.md | 8 +- docs/subsystems/skills.zh.md | 8 +- docs/subsystems/spill.i18n.yaml | 4 +- docs/subsystems/spill.md | 2 +- docs/subsystems/spill.zh.md | 2 +- docs/subsystems/subagent.i18n.yaml | 4 +- docs/subsystems/subagent.md | 30 +- docs/subsystems/subagent.zh.md | 30 +- docs/subsystems/subprocess.i18n.yaml | 4 +- docs/subsystems/subprocess.md | 16 +- docs/subsystems/subprocess.zh.md | 16 +- docs/subsystems/telemetry.i18n.yaml | 6 - .../{tasks.i18n.yaml => terminal.i18n.yaml} | 6 +- docs/subsystems/{pty.md => terminal.md} | 70 +- docs/subsystems/{pty.zh.md => terminal.zh.md} | 70 +- docs/subsystems/token-meter.i18n.yaml | 4 +- docs/subsystems/token-meter.md | 4 +- docs/subsystems/token-meter.zh.md | 4 +- docs/subsystems/tools.i18n.yaml | 4 +- docs/subsystems/tools.md | 22 +- docs/subsystems/tools.zh.md | 22 +- docs/subsystems/typert.i18n.yaml | 4 +- docs/subsystems/typert.md | 52 +- docs/subsystems/typert.zh.md | 52 +- docs/subsystems/user-interaction.i18n.yaml | 6 - ...ver.i18n.yaml => user-questions.i18n.yaml} | 6 +- ...{user-interaction.md => user-questions.md} | 30 +- ...interaction.zh.md => user-questions.zh.md} | 30 +- ...mission.i18n.yaml => web-server.i18n.yaml} | 6 +- .../{http-server.md => web-server.md} | 12 +- .../{http-server.zh.md => web-server.zh.md} | 12 +- docs/subsystems/web.i18n.yaml | 4 +- docs/subsystems/web.md | 10 +- docs/subsystems/web.zh.md | 10 +- docs/subsystems/workflow.i18n.yaml | 4 +- docs/subsystems/workflow.md | 8 +- docs/subsystems/workflow.zh.md | 8 +- docs/subsystems/workspace.i18n.yaml | 4 +- docs/subsystems/workspace.md | 12 +- docs/subsystems/workspace.zh.md | 12 +- docs/testing.i18n.yaml | 4 +- docs/testing.md | 6 +- docs/testing.zh.md | 6 +- docs/tool-catalog.i18n.yaml | 4 +- docs/tool-catalog.md | 130 +- docs/tool-catalog.zh.md | 120 +- docs/user/develop/framework/events.i18n.yaml | 4 +- docs/user/develop/framework/events.md | 2 +- docs/user/develop/framework/events.zh.md | 2 +- docs/user/develop/framework/service.i18n.yaml | 4 +- docs/user/develop/framework/service.md | 2 +- docs/user/develop/framework/service.zh.md | 2 +- docs/user/develop/practice/index.i18n.yaml | 4 +- docs/user/develop/practice/index.md | 4 +- docs/user/develop/practice/index.zh.md | 4 +- .../acp-agent/advanced.cordis.snapshot.yml | 2 +- examples/acp-agent/advanced.cordis.yml | 2 +- ...=> agent-instructions.cordis.snapshot.yml} | 2 +- ...rdis.yml => agent-instructions.cordis.yml} | 0 ...kground-job-admission.cordis.snapshot.yml} | 4 +- ...ml => background-job-admission.cordis.yml} | 2 +- .../acp-agent/both-mode.cordis.snapshot.yml | 2 +- examples/acp-agent/both-mode.cordis.yml | 2 +- .../child-question.cordis.snapshot.yml | 4 +- examples/acp-agent/child-question.cordis.yml | 4 +- ...mode-workspace-context.cordis.snapshot.yml | 2 +- .../code-mode-workspace-context.cordis.yml | 4 +- .../acp-agent/code-mode.cordis.snapshot.yml | 2 +- examples/acp-agent/code-mode.cordis.yml | 2 +- examples/acp-agent/composition.md | 42 +- examples/acp-agent/cordis.yml | 34 +- examples/acp-agent/pty-snapshot-backend.mjs | 4 +- examples/acp-agent/pty.cordis.snapshot.yml | 6 +- examples/acp-agent/pty.cordis.yml | 10 +- .../session-query.cordis.snapshot.yml | 2 +- examples/acp-agent/session-query.cordis.yml | 2 +- .../session-title.cordis.snapshot.yml | 2 +- examples/acp-agent/session-title.cordis.yml | 4 +- examples/acp-agent/tests/acp.snapshot.ts | 20 +- .../tests/fixtures/child-question-tripwire.ts | 6 +- .../{bash => shell}/tool-pwsh/cordis.yml | 10 +- .../{bash => shell}/tool-pwsh/driver.ts | 6 +- .../fixtures/workspace-context-compaction.ts | 4 +- .../tests/fs-search.cordis.snapshot.yml | 2 +- examples/acp-agent/tests/fs-search.cordis.yml | 2 +- .../input.json | 0 .../replay.override.json | 4 +- .../session.expected.jsonl | 24 +- .../session.jsonl | 0 .../stdout.expected.jsonl | 0 examples/acp-agent/tests/goal.snapshot.ts | 4 +- .../acp-agent/tests/lsp.cordis.snapshot.yml | 6 +- examples/acp-agent/tests/lsp.cordis.yml | 6 +- .../acp-agent/tests/pwsh.cordis.snapshot.yml | 6 +- examples/acp-agent/tests/pwsh.cordis.yml | 6 +- .../advanced-toolchain/session.1.jsonl | 2 +- .../advanced-toolchain/session.2.jsonl | 2 +- .../system-prompt.expected.md | 122 +- .../tool-schemas.expected.json | 110 +- .../input.json | 0 .../replay.override.json | 0 .../session.jsonl | 10 +- .../stdout.expected.jsonl | 0 .../system-prompt.expected.md | 8 +- .../workspace/.dsh-project | 0 .../workspace/AGENTS.canonical.md | 0 .../workspace/AGENTS.md | 0 .../workspace/nested/AGENTS.canonical.md | 0 .../workspace/nested/AGENTS.md | 0 .../workspace/nested/task.txt | 0 .../input.json | 2 +- .../replay.override.json | 12 +- .../session.jsonl | 36 +- .../stdout.expected.jsonl | 0 .../both-mode-turn/system-prompt.expected.md | 120 +- .../both-mode-turn/tool-schemas.expected.json | 108 +- .../code-mode-turn/system-prompt.expected.md | 120 +- .../code-mode-workspace-context/session.jsonl | 6 +- .../cordis-inspect-jsdoc/session.jsonl | 2 +- .../system-prompt.expected.md | 2 +- .../tool-schemas.expected.json | 4 +- .../hook-cc-posttool-block/session.jsonl | 8 +- .../hook-cc-posttool-context/session.jsonl | 8 +- .../hook-cc-pretool-ask/session.jsonl | 4 +- .../hook-cc-pretool-deny/session.jsonl | 4 +- .../session.jsonl | 6 +- .../hook-cc-stop-continue/session.jsonl | 12 +- .../lsp-definition/system-prompt.expected.md | 8 +- .../lsp-definition/tool-schemas.expected.json | 108 +- .../missing-sandbox-runner/input.json | 2 +- .../missing-sandbox-runner/session.jsonl | 18 +- .../snapshots/packed-chunks/session.jsonl | 4 +- .../tool-schemas.expected.json | 108 +- .../system-prompt.expected.md | 8 +- .../tool-schemas.expected.json | 108 +- .../pty-tools/system-prompt.expected.md | 10 +- .../pty-tools/tool-schemas.expected.json | 112 +- .../pwsh-tool-turn/system-prompt.expected.md | 4 +- .../pwsh-tool-turn/tool-schemas.expected.json | 28 +- .../read-image/tool-schemas.expected.json | 108 +- .../input.json | 0 .../session.jsonl | 8 +- .../stdout.expected.jsonl | 0 .../system-prompt.expected.md | 8 +- .../tool-schemas.expected.json | 108 +- .../session-title-after-turn/session.jsonl | 4 +- .../session.1.jsonl | 2 +- .../tool-schemas.expected.json | 108 +- .../system-prompt.1.expected.md | 8 +- .../tool-schemas.1.expected.json | 108 +- .../system-prompt.1.expected.md | 8 +- .../tool-schemas.1.expected.json | 108 +- .../session.1.jsonl | 2 +- .../session.2.jsonl | 2 +- .../input.json | 0 .../session.1.jsonl | 0 .../session.jsonl | 0 .../stdout.expected.jsonl | 0 .../system-prompt.1.expected.md | 8 +- .../tool-schemas.1.expected.json | 108 +- .../snapshots/subagent-mixed/session.1.jsonl | 2 +- .../snapshots/subagent-mixed/session.2.jsonl | 2 +- .../snapshots/subagent-multi/session.1.jsonl | 2 +- .../snapshots/subagent-multi/session.2.jsonl | 2 +- .../subagent-parallel/session.1.jsonl | 8 +- .../subagent-parallel/session.2.jsonl | 8 +- .../system-prompt.1.expected.md | 8 +- .../tool-schemas.1.expected.json | 108 +- .../input.json | 0 .../session.1.jsonl | 0 .../session.jsonl | 0 .../stdout.expected.jsonl | 0 .../text-turn/system-prompt.expected.md | 8 +- .../text-turn/tool-schemas.expected.json | 108 +- .../web-fetch/system-prompt.expected.md | 8 +- .../web-fetch/tool-schemas.expected.json | 108 +- .../acp-agent/web-fetch-fixture-server.mjs | 2 +- examples/acp-agent/web.cordis.snapshot.yml | 4 +- examples/acp-agent/web.cordis.yml | 4 +- .../advanced.cordis.snapshot.yml | 2 +- examples/headless-agent/advanced.cordis.yml | 2 +- .../compaction.cordis.snapshot.yml | 4 +- examples/headless-agent/composition.md | 34 +- examples/headless-agent/cordis.yml | 22 +- examples/headless-agent/e2b.cordis.yml | 14 +- .../headless-agent/pty.cordis.snapshot.yml | 6 +- .../semantic-checkpoint.cordis.snapshot.yml | 2 +- .../subagent-diagnostic.cordis.snapshot.yml | 4 +- .../subagent-inheritance.cordis.snapshot.yml | 10 +- .../headless-agent/tests/code-mode.e2e.ts | 80 +- .../headless-agent/tests/compaction.e2e.ts | 8 +- .../tests/fixtures/cli.cordis.yml | 2 +- .../tests/fixtures/e2b/e2b/bin.ts | 26 +- .../tests/fixtures/e2b/e2b/cordis.yml | 10 +- ...er.ts => session-telemetry-otel-driver.ts} | 4 +- ....yml => session-telemetry-otel.cordis.yml} | 4 +- .../tests/fixtures/telemetry-redact-rule.ts | 4 +- .../workspace-context-resume-agent.ts | 2 +- examples/headless-agent/tests/harness.ts | 28 +- .../headless-agent/tests/headless.snapshot.ts | 14 +- .../tests/semantic-checkpoint.snapshot.ts | 4 +- .../tests/session-format-guard.snapshot.ts | 4 +- .../advanced-toolchain/session.1.jsonl | 10 +- .../advanced-toolchain/session.2.jsonl | 10 +- .../advanced-toolchain/session.jsonl | 28 +- .../snapshots/compaction-recovery/input.json | 2 +- .../compaction-recovery/session.jsonl | 20 +- .../stream-json.expected.jsonl | 10 +- .../headless-profile/session.expected.jsonl | 2 +- .../tests/snapshots/pty-tools/session.jsonl | 34 +- .../stream-json.expected.jsonl | 4 +- .../parent.expected.jsonl | 4 +- .../tests/subagent-diagnostic.snapshot.ts | 6 +- .../tests/subagent-inheritance.snapshot.ts | 4 +- .../offline-edit/session.expected.jsonl | 4 +- .../precedence-change/session.expected.jsonl | 4 +- .../workspace-context-resume.snapshot.ts | 20 +- ...rkspace-context-resume.cordis.snapshot.yml | 2 +- examples/jsonrpc-agent/README.i18n.yaml | 2 +- examples/jsonrpc-agent/README.md | 2 +- examples/jsonrpc-agent/cordis.yml | 18 +- examples/jsonrpc-agent/minimal.cordis.yml | 12 +- .../subagent-dsh-sdk/child.cordis.yml | 6 +- .../jsonrpc-agent/tests/keyless-smoke.e2e.ts | 2 +- examples/jsonrpc-agent/tests/sdk.snapshot.ts | 2 +- .../notifications.expected.jsonl | 0 .../result.expected.json | 0 .../session.1.jsonl | 0 .../session.jsonl | 0 examples/package.json | 56 +- examples/web-cordis/README.i18n.yaml | 4 +- examples/web-cordis/README.md | 4 +- examples/web-cordis/README.zh.md | 4 +- examples/web-schedule/cordis.yml | 4 +- knip.json | 34 +- package.json | 4 +- packages/AGENTS.md | 4 +- packages/README.i18n.yaml | 4 +- packages/README.md | 15 +- packages/README.zh.md | 15 +- packages/acp/acp/tsconfig.json | 2 +- packages/api/README.i18n.yaml | 4 +- packages/api/README.md | 6 +- packages/api/README.zh.md | 6 +- packages/api/gateway/README.i18n.yaml | 4 +- packages/api/gateway/README.md | 10 +- packages/api/gateway/README.zh.md | 10 +- packages/api/gateway/package.json | 4 +- packages/api/gateway/src/client/index.ts | 52 +- packages/api/gateway/src/index.ts | 42 +- packages/api/gateway/src/invariant.ts | 2 +- packages/api/gateway/src/types.ts | 4 +- .../api/gateway/tests/gateway.client.spec.ts | 30 +- .../api/gateway/tests/gateway.host.spec.ts | 72 +- packages/api/gateway/tsconfig.client.json | 2 +- packages/api/gateway/tsconfig.host.json | 4 +- packages/api/remotes/README.i18n.yaml | 4 +- packages/api/remotes/README.md | 8 +- packages/api/remotes/README.zh.md | 8 +- packages/api/remotes/package.json | 2 +- packages/api/remotes/src/agent-lookup.ts | 8 +- packages/api/remotes/src/client/index.ts | 10 +- packages/api/remotes/src/index.ts | 4 +- packages/api/remotes/src/invariant.ts | 2 +- packages/api/remotes/src/types.ts | 4 +- .../api/remotes/tests/agent-lookup.spec.ts | 4 +- packages/api/remotes/tests/built-lib.e2e.ts | 2 +- packages/api/remotes/tsconfig.client.json | 2 +- packages/api/remotes/tsconfig.host.json | 4 +- .../attachment/attachment-local/package.json | 4 +- .../attachment/attachment-local/src/index.ts | 2 +- .../attachment/attachment-local/tsconfig.json | 4 +- packages/attachment/attachment/tsconfig.json | 2 +- packages/bash/bash-env/README.md | 51 - packages/bash/bash-env/README.zh.md | 51 - packages/bash/bash/README.zh.md | 53 - packages/bash/pwsh-local/README.i18n.yaml | 6 - packages/bash/pwsh-sandbox/README.i18n.yaml | 6 - packages/bash/tool-bash/README.i18n.yaml | 6 - packages/bash/tool-pwsh/README.i18n.yaml | 6 - packages/boot/app-boot/README.i18n.yaml | 4 +- packages/boot/app-boot/README.md | 2 +- packages/boot/app-boot/README.zh.md | 2 +- packages/boot/app-boot/package.json | 8 +- packages/boot/app-boot/src/index.ts | 10 +- packages/boot/app-boot/src/profile.ts | 6 +- packages/boot/app-boot/tests/app-boot.spec.ts | 2 +- packages/boot/app-boot/tsconfig.json | 6 +- packages/boot/cmdline/tsconfig.json | 2 +- packages/bundle/base/cordis.patch.yml | 70 +- packages/bundle/base/package.json | 36 +- packages/bundle/base/tests/base.spec.ts | 2 +- packages/bundle/base/tsconfig.json | 2 +- packages/bundle/headless/cordis.patch.yml | 2 +- packages/bundle/headless/package.json | 2 +- .../bundle/headless/tests/headless.spec.ts | 4 +- packages/bundle/headless/tsconfig.json | 2 +- packages/bundle/web-app/README.i18n.yaml | 4 +- packages/bundle/web-app/README.md | 2 +- packages/bundle/web-app/README.zh.md | 2 +- packages/bundle/web-app/cordis.patch.yml | 80 +- packages/bundle/web-app/package.json | 34 +- packages/bundle/web-app/src/index.ts | 26 +- packages/bundle/web-app/tests/web-app.spec.ts | 32 +- packages/bundle/web-app/tsconfig.json | 4 +- packages/client/AGENTS.md | 4 +- packages/client/README.i18n.yaml | 4 +- packages/client/README.md | 20 +- packages/client/README.zh.md | 20 +- packages/client/connection/README.i18n.yaml | 4 +- packages/client/connection/README.md | 2 +- packages/client/connection/README.zh.md | 2 +- packages/client/connection/src/client/api.ts | 2 +- .../client/connection/src/client/fixture.ts | 4 +- .../client/connection/src/client/index.ts | 2 +- packages/client/connection/src/index.ts | 8 +- packages/client/connection/src/rpc-host.ts | 2 +- .../connection/tests/node-half.host.spec.ts | 18 +- .../client/connection/tsconfig.client.json | 2 +- packages/client/connection/tsconfig.host.json | 2 +- packages/client/hmr/src/index.ts | 20 +- .../client/hmr/tests/node-half.client.spec.ts | 18 +- packages/client/hmr/tsconfig.json | 2 +- packages/client/locale/README.i18n.yaml | 4 +- packages/client/locale/README.md | 2 +- packages/client/locale/README.zh.md | 2 +- packages/client/locale/src/client/index.ts | 6 +- .../client/locale/tests/apply.client.spec.ts | 22 +- .../client/locale/tests/host.client.spec.ts | 4 +- .../locale/tests/invariant.client.spec.ts | 16 +- .../locale/tests/language-row.client.spec.tsx | 2 +- .../client/locale/tests/locale.client.spec.ts | 8 +- packages/client/locale/tsconfig.json | 2 +- packages/client/modules/src/index.ts | 18 +- packages/client/modules/src/invariant.ts | 2 +- .../modules/tests/node-half.client.spec.ts | 14 +- packages/client/modules/tsconfig.json | 2 +- packages/client/runtime/README.i18n.yaml | 4 +- packages/client/runtime/README.md | 16 +- packages/client/runtime/README.zh.md | 16 +- packages/client/runtime/package.json | 6 +- .../client/runtime/src/client/agents/scope.ts | 4 +- .../runtime/src/client/contract/session.ts | 2 +- .../src/client/contract/sessions-port.ts | 2 +- packages/client/runtime/src/client/index.ts | 32 +- .../src/client/sessions/context-provenance.ts | 2 +- .../src/client/sessions/conversation.ts | 4 +- .../runtime/src/client/sessions/manager.ts | 26 +- .../runtime/src/client/sessions/provide.ts | 4 +- .../runtime/src/client/sessions/service.ts | 30 +- .../runtime/src/client/sessions/session.ts | 6 +- packages/client/runtime/src/client/slots.ts | 8 +- .../runtime/src/client/workspaces/service.ts | 4 +- .../runtime/tests/client-apply.client.spec.ts | 16 +- .../tests/context-provenance.client.spec.ts | Bin 4572 -> 4540 bytes .../conversation-assembler.client.spec.ts | 4 +- .../conversation-registry.client.spec.ts | 4 +- .../runtime/tests/event-script.client.ts | 4 +- .../runtime/tests/invariant.client.spec.ts | 10 +- .../runtime/tests/manager.client.spec.ts | 18 +- .../tests/sessions-service.client.spec.ts | 8 +- .../tests/slots-service.client.spec.ts | 8 +- .../tests/workspaces-service.client.spec.ts | 58 +- packages/client/runtime/tsconfig.json | 6 +- .../tests/invariant.client.spec.ts | 4 +- packages/client/schema-form/tsconfig.json | 2 +- .../tests/apply.client.spec.ts | 14 +- .../tests/invariant.client.spec.ts | 4 +- packages/client/ui-agent-preset/tsconfig.json | 4 +- .../tests/invariant.client.spec.ts | 4 +- packages/client/ui-attachment/tsconfig.json | 2 +- packages/client/ui-command/tsdown.config.ts | 3 - .../README.i18n.yaml | 6 +- .../{ui-command => ui-commands}/README.md | 8 +- .../{ui-command => ui-commands}/README.zh.md | 8 +- .../{ui-command => ui-commands}/package.json | 10 +- .../src/client/PopupSelectView.module.css | 0 .../src/client/PopupSelectView.tsx | 0 .../src/client/contract.ts | 10 +- .../src/client/directory.ts | 0 .../src/client/index.ts | 22 +- .../src/client/locales.ts | 0 .../src/client/popup.ts | 8 +- .../src/client/service.ts | 38 +- .../src/css-modules.d.ts | 0 .../{ui-command => ui-commands}/src/index.ts | 2 +- .../src/invariant.ts | 8 +- .../tests/browser-plugin.client.spec.ts | 38 +- .../tests/directory.client.spec.ts | 0 .../tests/popup-view.client.spec.tsx | 0 .../tests/popup.client.spec.ts | 0 .../tests/service.client.spec.ts | 20 +- .../{ui-command => ui-commands}/tsconfig.json | 4 +- .../tsdown.config.ts | 2 +- .../client/ui-conversation/README.i18n.yaml | 4 +- packages/client/ui-conversation/README.md | 12 +- packages/client/ui-conversation/README.zh.md | 10 +- packages/client/ui-conversation/package.json | 10 +- .../ui-conversation/src/client/apply.ts | 22 +- .../src/client/chat/ChatView.tsx | 2 +- .../src/client/chat/CompactionItem.tsx | 2 +- .../src/client/contract/slots.ts | 10 +- .../src/client/conversation-nodes/command.ts | 20 +- .../client/conversation-nodes/compaction.ts | 12 +- .../ui-conversation/src/client/index.ts | 2 +- .../src/client/input/blocks.ts | 2 +- .../src/client/input/contract.ts | 8 +- .../src/client/input/facade.ts | 38 +- .../ui-conversation/src/client/input/hub.ts | 28 +- .../src/client/input/machine.ts | 2 +- .../ui-conversation/src/client/service.ts | 16 +- .../src/client/skeleton/ConversationRoot.tsx | 2 +- .../src/client/skeleton/PermissionSelect.tsx | 2 +- .../tests/apply-inject.client.spec.tsx | 4 +- .../tests/assembly-surfaces.client.spec.tsx | 10 +- .../tests/chat-apply.client.spec.tsx | 4 +- .../tests/chat-branch-tails.client.spec.tsx | 28 +- .../tests/chat-view.client.spec.tsx | 2 +- ...nversation-node-definitions.client.spec.ts | 30 +- .../tests/enter-behavior-row.client.spec.tsx | 2 +- .../tests/gate-branch-tails.client.spec.tsx | 4 +- .../ui-conversation/tests/host.client.spec.ts | 4 +- .../tests/input-bar.client.spec.tsx | 6 +- .../tests/input-machine.client.spec.ts | 2 +- .../tests/input-matrix.client.spec.tsx | 4 +- .../tests/input-scenarios.client.spec.tsx | 44 +- .../tests/selection-survival.client.spec.tsx | 4 +- .../service-orchestration.client.spec.ts | 20 +- .../tests/skeleton.client.spec.tsx | 2 +- .../tests/views-type-chain.client.spec.tsx | 6 +- packages/client/ui-conversation/tsconfig.json | 6 +- .../tests/produced-files.client.spec.tsx | 6 +- packages/client/ui-deliverables/tsconfig.json | 2 +- .../README.i18n.yaml | 6 + .../README.md | 2 +- .../README.zh.md | 2 +- .../package.json | 4 +- .../src/client/DirectoryBrowser.module.css | 0 .../src/client/DirectoryBrowser.tsx | 0 .../src/client/flow.ts | 0 .../src/client/index.ts | 0 .../src/css-modules.d.ts | 0 .../src/index.ts | 0 .../src/invariant.ts | 8 +- .../tests/client-flow.client.spec.tsx | 12 +- .../tests/directory-browser.client.spec.tsx | 0 .../tsconfig.json | 2 +- .../tsdown.config.ts | 2 +- .../tests/client-flow.client.spec.tsx | 6 +- .../ui-directory-picker-native/tsconfig.json | 2 +- packages/client/ui-feedback/tsdown.config.ts | 3 - packages/client/ui-goal/src/client/slots.ts | 2 +- .../tests/browser-plugin.client.spec.tsx | 8 +- packages/client/ui-goal/tsconfig.json | 2 +- .../README.i18n.yaml | 6 +- packages/client/ui-input-trigger/README.md | 25 + packages/client/ui-input-trigger/README.zh.md | 25 + .../package.json | 4 +- .../src/client/MenuView.module.css | 0 .../src/client/MenuView.tsx | 2 +- .../src/client/contract.ts | 14 +- .../src/client/controller.ts | 34 +- .../src/client/index.ts | 30 +- .../src/client/locales.ts | 0 .../src/client/service.ts | 30 +- .../src/client/slots.ts | 4 +- .../src/core/contract.ts | 8 +- .../src/core/detect.ts | 0 .../src/core/menu.ts | 4 +- .../src/css-modules.d.ts | 0 .../src/index.ts | 0 .../src/invariant.ts | 8 +- .../src/types.ts | 16 +- .../tests/apply.client.spec.ts | 30 +- .../tests/core-detect.client.spec.ts | 0 .../tests/core-menu.client.spec.ts | 0 .../tests/menu-view.client.spec.tsx | 4 +- .../tests/service.client.spec.ts | 126 +- .../tsconfig.json | 2 +- .../client/ui-input-trigger/tsdown.config.ts | 3 + .../{ui-task => ui-jobs}/README.i18n.yaml | 6 +- packages/client/ui-jobs/README.md | 24 + .../client/{ui-task => ui-jobs}/README.zh.md | 8 +- .../client/{ui-task => ui-jobs}/package.json | 6 +- .../src/client/JobListAction.module.css} | 2 +- .../src/client/JobListAction.tsx} | 76 +- .../{ui-task => ui-jobs}/src/client/index.ts | 22 +- .../src/client/locales.ts | 20 +- .../src/css-modules.d.ts | 0 .../client/{ui-task => ui-jobs}/src/index.ts | 2 +- .../{ui-task => ui-jobs}/src/invariant.ts | 10 +- .../tests/browser-plugin.client.spec.ts | 30 +- .../tests/job-list-action.client.spec.tsx} | 118 +- .../client/{ui-task => ui-jobs}/tsconfig.json | 2 +- .../{ui-task => ui-jobs}/tsdown.config.ts | 2 +- packages/client/ui-layout/README.i18n.yaml | 4 +- packages/client/ui-layout/README.md | 2 +- packages/client/ui-layout/README.zh.md | 2 +- packages/client/ui-layout/src/client/index.ts | 6 +- .../client/ui-layout/src/client/service.ts | 4 +- .../ui-layout/tests/apply.client.spec.ts | 20 +- .../ui-layout/tests/service.client.spec.ts | 12 +- packages/client/ui-layout/tsconfig.json | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 6 +- .../README.zh.md | 6 +- .../package.json | 8 +- .../client/MessageFeedbackActions.module.css} | 0 .../src/client/MessageFeedbackActions.tsx} | 8 +- .../src/client/controller.ts | 60 +- .../src/client/index.ts | 28 +- .../src/client/locales.ts | 6 +- .../src/client/slots.ts | 22 +- .../src/css-modules.d.ts | 0 .../src/index.ts | 0 .../src/invariant.ts | 6 +- .../tests/browser-plugin.client.spec.tsx | 16 +- .../tests/controller.client.spec.ts | 82 +- .../message-feedback-actions.client.spec.tsx} | 40 +- .../tsconfig.json | 4 +- .../ui-message-feedback/tsdown.config.ts | 3 + .../README.i18n.yaml | 6 +- .../README.md | 8 +- .../README.zh.md | 8 +- .../package.json | 14 +- .../src/client/ModelSelect.module.css | 0 .../src/client/ModelSelect.tsx | 0 .../src/client/directory.ts | 0 .../src/client/index.ts | 28 +- .../src/client/locales.ts | 0 .../src/client/service.ts | 24 +- .../src/client/slots.ts | 0 .../src/css-modules.d.ts | 0 .../src/index.ts | 0 .../src/invariant.ts | 8 +- .../tests/browser-plugin.client.spec.ts | 20 +- .../tests/model-select.client.spec.tsx | 0 .../tsconfig.json | 6 +- .../ui-model-selection/tsdown.config.ts | 3 + packages/client/ui-model/tsdown.config.ts | 3 - packages/client/ui-models/tsdown.config.ts | 3 - .../ui-permission-presets/README.i18n.yaml | 6 + .../README.md | 4 +- .../README.zh.md | 4 +- .../package.json | 18 +- .../src/client/PermissionRow.module.css | 0 .../src/client/PermissionRow.tsx | 0 .../src/client/index.ts | 14 +- .../src/client/locales.ts | 0 .../src/client/presentation.ts | 0 .../src/client/settings-store.ts | 4 +- .../src/css-modules.d.ts | 0 .../src/index.ts | 0 .../src/invariant.ts | 8 +- .../tests/browser-plugin.client.spec.ts | 14 +- .../permission-presets-row.client.spec.tsx} | 14 +- .../tests/settings-store.client.spec.ts | 22 +- .../tsconfig.json | 8 +- .../tsdown.config.ts | 2 +- .../client/ui-permission/README.i18n.yaml | 6 - .../tests/browser-plugin.client.spec.ts | 16 +- packages/client/ui-plan/tsconfig.json | 2 +- .../client/ui-plugin-config/README.i18n.yaml | 6 - .../client/ui-plugin-config/tsdown.config.ts | 3 - packages/client/ui-plugins/README.i18n.yaml | 6 - packages/client/ui-plugins/tsdown.config.ts | 3 - .../tests/code-block.client.spec.tsx | 2 +- .../tests/invariant.client.spec.ts | 4 +- .../tests/markdown-plain-text.client.spec.ts | 6 +- packages/client/ui-primitives/tsconfig.json | 2 +- packages/client/ui-question/README.i18n.yaml | 6 - .../tests/apply.client.spec.ts | 14 +- .../tests/host.client.spec.ts | 4 +- .../tests/invariant.client.spec.ts | 4 +- .../tests/shell.client.spec.ts | 10 +- .../client/ui-settings-general/tsconfig.json | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 2 +- .../README.zh.md | 2 +- .../package.json | 4 +- .../src/client/CustomProviderCard.tsx | 0 .../src/client/DeepSeekModelsEditor.tsx | 0 .../DeepSeekOnboardingDialog.module.css | 0 .../src/client/DeepSeekOnboardingDialog.tsx | 0 .../src/client/EditorFooter.tsx | 2 +- .../src/client/ModelListEditor.tsx | 0 .../src/client/ModelsSection.module.css | 0 .../src/client/ModelsSection.tsx | 0 .../src/client/ProviderEditor.tsx | 0 .../src/client/apiKey.ts | 2 +- .../src/client/index.ts | 4 +- .../src/client/locales.ts | 0 .../src/client/store.ts | 0 .../src/css-modules.d.ts | 0 .../src/index.ts | 0 .../src/invariant.ts | 8 +- .../tests/apply.client.spec.ts | 16 +- .../tests/components.client.spec.tsx | 0 .../tests/invariant.client.spec.ts | 8 +- .../tests/onboarding-dialog.client.spec.tsx | 0 .../tests/provider-form.client.spec.tsx | 0 .../tests/readiness.client.spec.ts | 0 .../tests/store.client.spec.ts | 0 .../tests/styles.client.spec.ts | 0 .../tsconfig.json | 2 +- .../ui-settings-models/tsdown.config.ts | 3 + .../README.i18n.yaml | 6 + .../README.md | 2 +- .../README.zh.md | 2 +- .../package.json | 4 +- .../PluginInventorySettingsTab.module.css} | 0 .../client/PluginInventorySettingsTab.tsx} | 18 +- .../src/client/index.ts | 20 +- .../src/client/locales.ts | 4 +- .../src/css-modules.d.ts | 0 .../src/index.ts | 0 .../src/invariant.ts | 6 +- .../tests/browser-plugin.client.spec.tsx | 24 +- .../tests/components.client.spec.tsx | 36 +- .../tests/invariant.client.spec.ts | 6 +- .../tsconfig.json | 2 +- .../tsdown.config.ts | 3 + .../ui-settings-plugins/README.i18n.yaml | 6 + .../README.md | 2 +- .../README.zh.md | 2 +- .../package.json | 4 +- .../src/client/AgentLoopCard.tsx | 4 +- .../src/client/BashCard.tsx | 4 +- .../src/client/ConfigurablePluginsTab.tsx | 4 +- .../src/client/PluginCard.module.css | 0 .../src/client/PluginCard.tsx | 10 +- .../client/PluginsSettingsSection.module.css} | 0 .../src/client/PluginsSettingsSection.tsx} | 22 +- .../src/client/WebSearchCard.tsx | 4 +- .../src/client/agent-loop-card-controller.ts} | 2 +- .../src/client/bash-card-controller.ts} | 4 +- .../src/client/card-form.ts} | 0 .../src/client/fields.module.css | 0 .../src/client/fields.tsx | 0 .../src/client/index.ts | 34 +- .../src/client/locales.ts | 6 +- .../src/client/slot-contract.ts | 0 .../src/client/web-search-card-controller.ts} | 2 +- .../src/css-modules.d.ts | 0 .../src/index.ts | 0 .../src/invariant.ts | 8 +- .../tests/apply.client.spec.ts | 26 +- .../tests/fields.client.spec.tsx | 0 .../tests/invariant.client.spec.ts | 8 +- .../tests/section.client.spec.tsx | 22 +- .../tests/stores.client.spec.ts | 8 +- .../tsconfig.json | 4 +- .../ui-settings-plugins/tsdown.config.ts | 3 + .../client/ui-settings/src/client/index.ts | 6 +- .../ui-settings/src/client/settings-scope.ts | 4 +- .../tests/invariant.client.spec.ts | 4 +- .../ui-settings/tests/plugin.client.spec.ts | 4 +- .../tests/settings-scope.client.spec.ts | 8 +- packages/client/ui-settings/tsconfig.json | 2 +- .../ui-sidebar/tests/apply.client.spec.tsx | 10 +- .../ui-sidebar/tests/invariant.client.spec.ts | 4 +- .../tests/sidebar-snapshot.client.spec.tsx | 4 +- packages/client/ui-sidebar/tsconfig.json | 2 +- packages/client/ui-skill/README.i18n.yaml | 4 +- packages/client/ui-skill/README.md | 2 +- packages/client/ui-skill/README.zh.md | 2 +- packages/client/ui-skill/package.json | 6 +- packages/client/ui-skill/src/client/index.ts | 12 +- .../tests/browser-plugin.client.spec.ts | 30 +- packages/client/ui-skill/tsconfig.json | 4 +- packages/client/ui-slash/README.i18n.yaml | 6 - packages/client/ui-slash/README.md | 25 - packages/client/ui-slash/README.zh.md | 25 - packages/client/ui-slash/tsdown.config.ts | 3 - packages/client/ui-slots/src/invariant.ts | 2 +- packages/client/ui-slots/src/renderer.ts | 4 +- .../ui-slots/tests/invariant.client.spec.ts | 4 +- packages/client/ui-slots/tsconfig.json | 2 +- packages/client/ui-subagent/README.i18n.yaml | 4 +- packages/client/ui-subagent/README.md | 4 +- packages/client/ui-subagent/README.zh.md | 4 +- packages/client/ui-subagent/package.json | 6 +- .../client/ui-subagent/src/client/index.ts | 10 +- .../tests/browser-plugin.client.spec.ts | 26 +- .../tests/conversation-ui.client.spec.tsx | 2 +- packages/client/ui-subagent/tsconfig.json | 4 +- packages/client/ui-task/README.md | 24 - packages/client/ui-theme/README.i18n.yaml | 4 +- packages/client/ui-theme/README.md | 4 +- packages/client/ui-theme/README.zh.md | 4 +- packages/client/ui-theme/package.json | 2 +- packages/client/ui-theme/src/client/index.ts | 6 +- packages/client/ui-theme/src/index.ts | 4 +- .../tests/appearance-row.client.spec.tsx | 2 +- .../ui-theme/tests/apply.client.spec.ts | 30 +- .../client/ui-theme/tests/host.client.spec.ts | 14 +- .../ui-theme/tests/invariant.client.spec.ts | 12 +- .../ui-theme/tests/theme.client.spec.ts | 8 +- packages/client/ui-theme/tsconfig.json | 2 +- packages/client/ui-tool/README.i18n.yaml | 4 +- packages/client/ui-tool/README.md | 2 +- packages/client/ui-tool/README.zh.md | 2 +- .../tool/toolviews/ask-question-row.tsx | 2 +- .../tests/ask-question-row.client.spec.tsx | 4 +- .../tests/assembly-surfaces.client.spec.tsx | 4 +- .../tests/chat-code-subcalls.client.spec.tsx | 16 +- .../tests/coverage-tails.client.spec.tsx | 2 +- .../ui-tool/tests/diff-card.client.spec.tsx | 6 +- .../ui-tool/tests/read-card.client.spec.tsx | 6 +- .../ui-tool/tests/search-card.client.spec.tsx | 2 +- .../tests/terminal-card.client.spec.tsx | 8 +- .../tests/toolview-slot.client.spec.tsx | 8 +- .../tests/toolview-type-chain.client.spec.tsx | 4 +- .../ui-tool/tests/web-card.client.spec.tsx | 2 +- packages/client/ui-tool/tsconfig.json | 2 +- packages/client/ui-trajectory/package.json | 4 +- .../trajectory-compaction-definition.ts | 28 +- .../tests/client-bundle.client.spec.ts | 6 +- .../conversation-definitions.client.spec.ts | 8 +- .../ui-trajectory/tests/table.client.spec.tsx | 6 +- .../ui-trajectory/tests/views.client.spec.tsx | 16 +- packages/client/ui-trajectory/tsconfig.json | 4 +- .../README.i18n.yaml | 6 +- .../README.md | 2 +- .../README.zh.md | 2 +- .../package.json | 6 +- .../src/client/PlanReviewPanel.module.css | 0 .../src/client/PlanReviewPanel.tsx | 0 .../src/client/QuestionComposer.module.css | 0 .../src/client/QuestionComposer.tsx | 0 .../src/client/contract/slots.ts | 0 .../src/client/index.ts | 2 +- .../src/client/locales.ts | 0 .../src/css-modules.d.ts | 0 .../src/index.ts | 0 .../src/invariant.ts | 8 +- .../tests/browser-plugin.client.spec.ts | 16 +- .../tests/node-plugin.client.spec.ts | 10 +- .../tests/plan-review-panel.client.spec.tsx | 0 .../user-questions-composer.client.spec.tsx} | 0 .../tsconfig.json | 2 +- .../client/ui-user-questions/tsdown.config.ts | 3 + .../client/ui-workflow-run/README.i18n.yaml | 4 +- packages/client/ui-workflow-run/README.md | 2 +- packages/client/ui-workflow-run/README.zh.md | 2 +- .../src/client/WorkflowRunPanel.tsx | 2 +- .../tests/workflow-run.client.spec.tsx | 6 +- packages/client/ui-workflow-run/tsconfig.json | 2 +- .../src/client/WorkspaceBrowser.tsx | 130 +- .../client/ui-workspace/src/client/stores.ts | 64 +- .../client/ui-workspace/src/client/tree.ts | 10 +- .../ui-workspace/tests/apply.client.spec.ts | 12 +- .../tests/invariant.client.spec.ts | 4 +- .../tests/rename-assembly.client.spec.tsx | 4 +- .../ui-workspace/tests/tree.client.spec.ts | 52 +- .../tests/workspace-browser.client.spec.tsx | 50 +- .../tests/workspace-picker.client.spec.tsx | 2 +- packages/client/ui-workspace/tsconfig.json | 2 +- packages/client/web-react/README.i18n.yaml | 4 +- packages/client/web-react/README.md | 2 +- packages/client/web-react/README.zh.md | 2 +- .../client/web-react/src/scoped-slots.tsx | 2 +- .../tests/scoped-slots.client.spec.tsx | 2 +- packages/client/web-react/tsconfig.json | 2 +- .../web/tests/app-shell.client.spec.tsx | 8 +- packages/client/web/tsconfig.json | 2 +- packages/code-runtime/README.i18n.yaml | 4 +- packages/code-runtime/README.md | 2 +- packages/code-runtime/README.zh.md | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 8 +- .../README.zh.md | 8 +- .../package.json | 4 +- .../src/bootstrap.ts | 2 +- .../src/index.ts | 28 +- .../src/invariant.ts | 8 +- .../src/output-json.ts | 2 +- .../src/protocol.ts | 2 +- .../src/worker-json.ts | 5 +- .../src/worker.ts | 4 +- .../tests/bootstrap.spec.ts | 0 .../tests/built-lib.e2e.ts | 4 +- .../tests/output-json.spec.ts | 0 .../tests/runtime.spec.ts | 34 +- .../tests/source-worker.compat.spec.ts | 0 .../tests/worker-json.spec.ts | 0 .../tsconfig.json | 2 +- .../tsdown.config.ts | 0 .../code-runtime/code-runtime/tsconfig.json | 2 +- packages/compact/README.md | 16 - .../{compact => compaction}/README.i18n.yaml | 6 +- packages/compaction/README.md | 16 + packages/{compact => compaction}/README.zh.md | 10 +- .../command-compact/README.i18n.yaml | 6 +- .../command-compact/README.md | 14 +- .../command-compact/README.zh.md | 14 +- .../command-compact/package.json | 6 +- .../command-compact/src/index.ts | 6 +- .../command-compact/src/invariant.ts | 0 .../tests/command-compact.spec.ts | 32 +- .../command-compact/tests/invariant.spec.ts | 0 .../tests/loader-composition.spec.ts | 30 +- .../command-compact/tsconfig.json | 4 +- .../compaction-basic}/README.i18n.yaml | 6 +- .../compaction-basic}/README.md | 40 +- .../compaction-basic}/README.zh.md | 40 +- .../compaction-basic}/package.json | 14 +- .../compaction-basic}/src/config.ts | 36 +- .../compaction-basic}/src/index.ts | 32 +- .../compaction-basic}/src/invariant.ts | 8 +- .../compaction-basic}/src/region.ts | 38 +- .../compaction-basic}/src/summarizer.ts | 8 +- .../compaction-basic}/src/types.ts | 8 +- .../tests/compaction-basic.spec.ts} | 194 +- .../tests/compaction-loop-repro.spec.ts} | 44 +- .../tests/loader-composition.spec.ts | 52 +- .../tests/manual-compaction.spec.ts} | 142 +- .../compaction-basic}/tsconfig.json | 6 +- .../README.i18n.yaml | 6 +- .../compaction-tool-result-pruner}/README.md | 12 +- .../README.zh.md | 12 +- .../package.json | 8 +- .../src/config.ts | 0 .../src/index.ts | 18 +- .../src/invariant.ts | 8 +- .../src/types.ts | 0 .../tests/loader-composition.spec.ts | 20 +- .../tests/tool-result-pruner.spec.ts} | 30 +- .../tsconfig.json | 4 +- .../compaction}/README.i18n.yaml | 6 +- .../compaction}/README.md | 34 +- .../compaction}/README.zh.md | 34 +- .../compaction}/package.json | 6 +- .../compaction}/src/brand.ts | 0 .../compaction}/src/checkpoint.ts | 8 +- .../compaction}/src/index.ts | 32 +- .../compaction}/src/invariant.ts | 72 +- .../compaction}/src/tool-pairing.ts | 2 +- .../compaction}/src/types.ts | 26 +- .../compaction/tests/compaction.spec.ts} | 62 +- .../compaction}/tests/invariant.spec.ts | 190 +- .../compaction}/tests/tool-pairing.spec.ts | 2 +- .../compaction}/tsconfig.json | 2 +- .../compaction}/tsdown.config.ts | 0 packages/context/README.i18n.yaml | 4 +- packages/context/README.md | 8 +- packages/context/README.zh.md | 8 +- .../README.i18n.yaml | 6 +- .../README.md | 4 +- .../README.zh.md | 4 +- .../package.json | 8 +- .../src/config.ts | 4 +- .../src/digest.ts | 2 +- .../src/files.ts | 4 +- .../src/index.ts | 28 +- .../src/invariant.ts | 6 +- .../src/render.ts | 8 +- .../src/state.ts | 46 +- .../tests/agent-instructions.e2e.ts} | 12 +- .../tests/agent-instructions.spec.ts} | 144 +- .../tsconfig.json | 4 +- .../session-reference/README.i18n.yaml | 4 +- packages/context/session-reference/README.md | 6 +- .../context/session-reference/README.zh.md | 6 +- .../context/session-reference/package.json | 10 +- .../context/session-reference/src/index.ts | 8 +- .../session-reference/src/projection.ts | 4 +- .../tests/session-reference.spec.ts | 86 +- .../context/session-reference/tsconfig.json | 6 +- .../time-context/tests/invariant.spec.ts | 8 +- .../time-context/tests/time-context.spec.ts | 2 +- packages/context/time-context/tsconfig.json | 4 +- .../context/tmux-context/README.i18n.yaml | 4 +- packages/context/tmux-context/README.md | 4 +- packages/context/tmux-context/README.zh.md | 4 +- packages/context/tmux-context/package.json | 4 +- packages/context/tmux-context/src/index.ts | 12 +- .../tmux-context/tests/tmux-context.spec.ts | 22 +- packages/context/tmux-context/tsconfig.json | 4 +- .../core/agent-default-model/README.i18n.yaml | 4 +- packages/core/agent-default-model/README.md | 2 +- .../core/agent-default-model/README.zh.md | 2 +- .../core/agent-default-model/src/index.ts | 6 +- .../tests/agent-default-model.spec.ts | 14 +- .../core/agent-default-model/tsconfig.json | 2 +- packages/core/agent-loop/README.i18n.yaml | 4 +- packages/core/agent-loop/README.md | 2 +- packages/core/agent-loop/README.zh.md | 2 +- packages/core/agent-loop/src/agent.ts | 4 +- packages/core/agent-loop/src/index.ts | 16 +- packages/core/agent-loop/src/tool-calls.ts | 10 +- .../agent-loop/tests/agent-initiator.spec.ts | 16 +- packages/core/agent-loop/tests/agent.spec.ts | 8 +- packages/core/agent-loop/tests/cancel.spec.ts | 12 +- .../tests/config-session-id.spec.ts | 60 +- .../tests/contract-regressions.spec.ts | 42 +- .../agent-loop/tests/coverage-edges.spec.ts | 8 +- .../agent-loop/tests/interception.spec.ts | 8 +- .../core/agent-loop/tests/invariant.spec.ts | 6 +- packages/core/agent-loop/tests/loop.spec.ts | 28 +- .../core/agent-loop/tests/properties.spec.ts | 8 +- .../agent-loop/tests/request-cache.e2e.ts | 8 +- .../agent-loop/tests/request-error.spec.ts | 8 +- .../tests/request-reconstruction.spec.ts | 16 +- packages/core/agent-loop/tests/resume.spec.ts | 76 +- .../agent-loop/tests/scope-lifecycle.spec.ts | 10 +- .../core/agent-loop/tests/settings.spec.ts | 12 +- .../core/agent-loop/tests/tool-calls.spec.ts | 22 +- .../core/agent-loop/tests/tool-order.spec.ts | 8 +- packages/core/agent-loop/tsconfig.json | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 4 +- .../README.zh.md | 4 +- .../package.json | 4 +- .../src/index.ts | 6 +- .../src/invariant.ts | 8 +- .../tests/agent-tool-presentation.spec.ts} | 8 +- .../tsconfig.json | 2 +- packages/core/agent/package.json | 4 +- packages/core/agent/src/index.ts | 12 +- packages/core/agent/tests/agent.spec.ts | 2 +- packages/core/agent/tests/invariant.spec.ts | 4 +- packages/core/agent/tsconfig.json | 4 +- packages/core/scope/tests/invariant.spec.ts | 4 +- packages/core/scope/tsconfig.json | 2 +- packages/core/session/README.i18n.yaml | 4 +- packages/core/session/README.md | 4 +- packages/core/session/README.zh.md | 4 +- packages/core/session/package.json | 4 +- packages/core/session/src/index.ts | 10 +- .../core/session/src/known-event-types.ts | 8 +- packages/core/session/src/surface.ts | 2 +- packages/core/session/src/types.ts | 4 +- packages/core/session/tests/fork.spec.ts | 2 +- packages/core/session/tests/invariant.spec.ts | 6 +- packages/core/session/tests/session.spec.ts | 4 +- packages/core/session/tests/typert.spec.ts | 2 +- packages/core/session/tsconfig.json | 4 +- packages/core/system-prompt/README.i18n.yaml | 4 +- packages/core/system-prompt/README.md | 8 +- packages/core/system-prompt/README.zh.md | 8 +- packages/core/system-prompt/src/index.ts | 2 +- .../system-prompt/tests/invariant.spec.ts | 4 +- .../system-prompt/tests/system-prompt.spec.ts | 12 +- packages/core/system-prompt/tsconfig.json | 2 +- packages/core/tools/README.i18n.yaml | 4 +- packages/core/tools/README.md | 8 +- packages/core/tools/README.zh.md | 8 +- packages/core/tools/src/code-mode.ts | 8 +- packages/core/tools/src/index.ts | 38 +- packages/core/tools/src/presentation.ts | 2 +- packages/core/tools/tests/code-mode.spec.ts | 20 +- .../core/tools/tests/execution-mode.spec.ts | 6 +- .../core/tools/tests/gen-tool-catalog.spec.ts | 4 +- packages/core/tools/tests/invariant.spec.ts | 8 +- packages/core/tools/tests/scoped.spec.ts | 4 +- packages/core/tools/tests/tools.spec.ts | 8 +- packages/core/tools/tsconfig.json | 2 +- .../credentials-local/README.i18n.yaml | 4 +- .../credentials/credentials-local/README.md | 2 +- .../credentials-local/README.zh.md | 2 +- .../credentials-local/package.json | 8 +- .../credentials-local/src/index.ts | 26 +- .../credentials-local/tests/drain.spec.ts | 4 +- .../credentials-local/tests/local.spec.ts | 30 +- .../tests/review-fixes.spec.ts | 6 +- .../credentials-local/tests/watcher.spec.ts | 8 +- .../credentials-local/tsconfig.json | 6 +- packages/credentials/credentials/src/index.ts | 10 +- .../credentials/tests/invariant.spec.ts | 8 +- .../credentials/credentials/tests/memory.ts | 4 +- .../credentials/credentials/tsconfig.json | 2 +- packages/e2b/README.i18n.yaml | 4 +- packages/e2b/README.md | 2 +- packages/e2b/README.zh.md | 2 +- packages/e2b/e2b/src/index.ts | 6 +- packages/e2b/e2b/tests/composition.e2e.ts | 14 +- packages/e2b/e2b/tests/e2b.spec.ts | 28 +- packages/e2b/e2b/tsconfig.json | 2 +- packages/e2b/fs-e2b/tests/filesystem.spec.ts | 8 +- packages/e2b/fs-e2b/tsconfig.json | 2 +- packages/e2b/subprocess-e2b/README.i18n.yaml | 4 +- packages/e2b/subprocess-e2b/README.md | 2 +- packages/e2b/subprocess-e2b/README.zh.md | 2 +- packages/e2b/subprocess-e2b/src/index.ts | 6 +- packages/e2b/subprocess-e2b/src/process.ts | 4 +- packages/e2b/subprocess-e2b/src/terminal.ts | 4 +- .../subprocess-e2b/tests/subprocess.spec.ts | 20 +- .../e2b/subprocess-e2b/tests/terminal.spec.ts | 14 +- packages/e2b/subprocess-e2b/tsconfig.json | 2 +- packages/examples/README.i18n.yaml | 4 +- packages/examples/README.md | 2 +- packages/examples/README.zh.md | 2 +- packages/examples/acp-demo/README.i18n.yaml | 4 +- packages/examples/acp-demo/README.md | 4 +- packages/examples/acp-demo/README.zh.md | 4 +- packages/examples/acp-demo/package.json | 4 +- packages/examples/acp-demo/src/index.ts | 26 +- .../examples/acp-demo/tests/acp-agent.spec.ts | 26 +- .../examples/acp-demo/tests/built-bin.e2e.ts | 6 +- .../examples/acp-demo/tests/load-path.e2e.ts | 2 +- packages/examples/acp-demo/tsconfig.json | 4 +- .../agent-spine-demo/README.i18n.yaml | 4 +- packages/examples/agent-spine-demo/README.md | 20 +- .../examples/agent-spine-demo/README.zh.md | 18 +- .../examples/agent-spine-demo/package.json | 32 +- .../examples/agent-spine-demo/src/index.ts | 84 +- .../agent-spine-demo/tests/agent-core.spec.ts | 60 +- .../tests/multi-project-sandbox.e2e.ts | 8 +- .../examples/agent-spine-demo/tsconfig.json | 20 +- .../examples/jsonrpc-demo/README.i18n.yaml | 4 +- packages/examples/jsonrpc-demo/README.md | 6 +- packages/examples/jsonrpc-demo/README.zh.md | 6 +- packages/examples/jsonrpc-demo/package.json | 2 +- packages/examples/jsonrpc-demo/src/bin.ts | 2 +- packages/examples/jsonrpc-demo/src/index.ts | 4 +- .../examples/jsonrpc-demo/src/invariant.ts | 8 +- .../examples/jsonrpc-demo/src/packaged-bin.ts | 2 +- packages/examples/jsonrpc-demo/src/runner.ts | 2 +- packages/examples/jsonrpc-demo/tsconfig.json | 2 +- .../README.i18n.yaml | 2 +- .../README.md | 0 .../README.zh.md | 0 .../extensions/tool-cordis/README.i18n.yaml | 6 + .../tool-cordis/README.md | 4 +- .../tool-cordis/README.zh.md | 2 +- .../tool-cordis/package.json | 2 +- .../tool-cordis/src/api-catalog.ts | 682 ++++--- .../tool-cordis/src/fiber-state.ts | 0 .../tool-cordis/src/guard.ts | 2 +- .../tool-cordis/src/index.ts | 10 +- .../tool-cordis/src/inspect.ts | 0 .../tool-cordis/src/invariant.ts | 0 .../tool-cordis/src/mount.ts | 0 .../tool-cordis/src/present.ts | 0 .../tool-cordis/src/sandbox.ts | 2 +- .../tests/cordis-lifecycle.spec.ts | 0 .../tool-cordis/tests/cross-mount.spec.ts | 0 .../tool-cordis/tests/helpers.ts | 8 +- .../tool-cordis/tests/inspect.spec.ts | 10 +- .../tool-cordis/tests/integration.spec.ts | 0 .../tool-cordis/tests/mount.spec.ts | 0 .../tool-cordis/tests/present.spec.ts | 0 .../tool-cordis/tests/sandbox-context.spec.ts | 2 +- .../tool-cordis/tests/tool-cordis.spec.ts | 0 .../tool-cordis/tests/unmount-hmr.spec.ts | 4 +- .../tool-cordis/tsconfig.json | 2 +- .../command-feedback/README.i18n.yaml | 4 +- packages/feedback/command-feedback/README.md | 6 +- .../feedback/command-feedback/README.zh.md | 6 +- .../feedback/command-feedback/package.json | 4 +- .../feedback/command-feedback/src/index.ts | 12 +- .../tests/command-feedback.spec.ts | 28 +- .../tests/loader-composition.spec.ts | 8 +- .../feedback/command-feedback/tsconfig.json | 4 +- .../message-feedback/README.i18n.yaml | 4 +- packages/feedback/message-feedback/README.md | 2 +- .../feedback/message-feedback/README.zh.md | 2 +- .../feedback/message-feedback/package.json | 4 +- .../feedback/message-feedback/src/index.ts | 4 +- .../message-feedback/tests/invariant.spec.ts | 4 +- .../tests/loader-composition.spec.ts | 8 +- .../tests/message-feedback.spec.ts | 4 +- .../feedback/message-feedback/tsconfig.json | 4 +- packages/fs/README.i18n.yaml | 4 +- packages/fs/README.md | 4 +- packages/fs/README.zh.md | 4 +- packages/fs/fs-local/README.i18n.yaml | 4 +- packages/fs/fs-local/README.md | 2 +- packages/fs/fs-local/README.zh.md | 2 +- packages/fs/fs-local/tests/filesystem.spec.ts | 2 +- packages/fs/fs-local/tests/fsio.spec.ts | 2 +- packages/fs/fs-local/tsconfig.json | 2 +- .../fs/fs-observation-policy/README.i18n.yaml | 6 + .../README.md | 8 +- .../README.zh.md | 8 +- .../package.json | 4 +- .../src/index.ts | 14 +- .../src/invariant.ts | 8 +- .../src/types.ts | 8 +- .../tests/policy.spec.ts | 12 +- .../tsconfig.json | 2 +- packages/fs/fs-sandbox/README.i18n.yaml | 4 +- packages/fs/fs-sandbox/README.md | 4 +- packages/fs/fs-sandbox/README.zh.md | 4 +- packages/fs/fs-sandbox/src/index.ts | 2 +- packages/fs/fs-sandbox/tsconfig.json | 2 +- packages/fs/fs/README.i18n.yaml | 4 +- packages/fs/fs/README.md | 6 +- packages/fs/fs/README.zh.md | 6 +- packages/fs/fs/src/index.ts | 2 +- packages/fs/fs/tests/invariant.spec.ts | 4 +- packages/fs/fs/tests/service.spec.ts | 2 +- packages/fs/fs/tsconfig.json | 2 +- packages/fs/tool-fs-search/README.i18n.yaml | 4 +- packages/fs/tool-fs-search/README.md | 6 +- packages/fs/tool-fs-search/README.zh.md | 4 +- packages/fs/tool-fs-search/package.json | 4 +- packages/fs/tool-fs-search/src/grep.ts | 2 +- packages/fs/tool-fs-search/src/index.ts | 7 +- .../fs/tool-fs-search/src/presentation.ts | 2 +- packages/fs/tool-fs-search/src/search-core.ts | 10 +- .../tool-fs-search/tests/integration.spec.ts | 8 +- .../fs/tool-fs-search/tests/load-path.spec.ts | 8 +- .../fs/tool-fs-search/tests/tools.spec.ts | 18 +- packages/fs/tool-fs-search/tsconfig.json | 6 +- packages/fs/tool-fs/README.i18n.yaml | 4 +- packages/fs/tool-fs/README.md | 14 +- packages/fs/tool-fs/README.zh.md | 14 +- packages/fs/tool-fs/package.json | 2 +- packages/fs/tool-fs/src/edit.ts | 2 +- packages/fs/tool-fs/src/sandbox.ts | 2 +- packages/fs/tool-fs/src/write.ts | 2 +- packages/fs/tool-fs/tests/harness.ts | 2 +- packages/fs/tool-fs/tests/integration.spec.ts | 16 +- packages/fs/tool-fs/tests/read-image.spec.ts | 12 +- packages/fs/tool-fs/tests/tools.spec.ts | 18 +- packages/fs/tool-fs/tsconfig.json | 4 +- .../fs/tool-str-replace-editor/package.json | 2 +- .../tests/tools.spec.ts | 10 +- .../fs/tool-str-replace-editor/tsconfig.json | 2 +- packages/goal/README.i18n.yaml | 4 +- packages/goal/README.md | 2 +- packages/goal/README.zh.md | 2 +- .../command-goal/tests/command-goal.spec.ts | 6 +- packages/goal/command-goal/tsconfig.json | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 6 +- .../README.zh.md | 6 +- .../package.json | 4 +- .../src/index.ts | 24 +- .../src/invariant.ts | 8 +- .../src/prompt.ts | 0 .../tests/goal-round-driver.spec.ts} | 6 +- .../tests/invariant.spec.ts | 24 +- .../tsconfig.json | 2 +- .../tsdown.config.ts | 0 packages/goal/goal/package.json | 4 +- packages/goal/goal/src/index.ts | 4 +- packages/goal/goal/tests/invariant.spec.ts | 6 +- packages/goal/goal/tsconfig.json | 4 +- .../goal/tool-goal/tests/tool-goal.spec.ts | 8 +- packages/goal/tool-goal/tsconfig.json | 2 +- packages/guard/README.i18n.yaml | 4 +- packages/guard/README.md | 2 +- packages/guard/README.zh.md | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 10 +- .../README.zh.md | 10 +- .../package.json | 4 +- .../src/index.ts | 18 +- .../src/invariant.ts | 8 +- .../tests/repeat-tool-reminder.spec.ts} | 6 +- .../tsconfig.json | 2 +- .../guard/timeout-policy/README.i18n.yaml | 4 +- packages/guard/timeout-policy/README.md | 4 +- packages/guard/timeout-policy/README.zh.md | 4 +- packages/guard/timeout-policy/package.json | 2 +- packages/guard/timeout-policy/src/index.ts | 2 +- .../guard/timeout-policy/src/invariant.ts | 6 +- .../tests/timeout-policy.spec.ts | 16 +- packages/guard/timeout-policy/tsconfig.json | 2 +- packages/hooks/README.i18n.yaml | 4 +- packages/hooks/README.md | 2 +- packages/hooks/README.zh.md | 2 +- packages/hooks/hook-protocol/README.i18n.yaml | 4 +- packages/hooks/hook-protocol/README.md | 12 +- packages/hooks/hook-protocol/README.zh.md | 12 +- packages/hooks/hook-protocol/package.json | 4 +- packages/hooks/hook-protocol/src/invariant.ts | 2 +- packages/hooks/hook-protocol/src/matcher.ts | 4 +- packages/hooks/hook-protocol/src/runner.ts | 8 +- packages/hooks/hook-protocol/src/types.ts | 8 +- .../hooks/hook-protocol/tests/events.spec.ts | 6 +- .../hook-protocol/tests/invariant.spec.ts | 10 +- .../hooks/hook-protocol/tests/matcher.spec.ts | 34 +- .../hooks/hook-protocol/tests/runner.spec.ts | 20 +- packages/hooks/hook-protocol/tsconfig.json | 4 +- .../README.i18n.yaml | 6 +- .../README.md | 10 +- .../README.zh.md | 10 +- .../package.json | 6 +- .../src/config.ts | 12 +- .../src/index.ts | 38 +- .../src/invariant.ts | 8 +- .../tests/bridge.spec.ts | 42 +- .../tests/config.spec.ts | 36 +- .../tests/coverage-cases.ts | 54 +- .../tests/coverage-config.spec.ts | 0 .../tests/coverage-context.spec.ts | 0 .../tests/coverage-edge-paths.spec.ts | 0 .../tests/coverage-stop.spec.ts | 0 .../tsconfig.json | 4 +- packages/hooks/hooks-codex/package.json | 2 +- packages/hooks/hooks-codex/src/index.ts | 4 +- .../hooks/hooks-codex/tests/bridge.spec.ts | 12 +- .../hooks/hooks-codex/tests/coverage-cases.ts | 14 +- packages/hooks/hooks-codex/tsconfig.json | 4 +- packages/host/README.i18n.yaml | 4 +- packages/host/README.md | 6 +- packages/host/README.zh.md | 6 +- packages/host/apiproxy/README.i18n.yaml | 4 +- packages/host/apiproxy/README.md | 6 +- packages/host/apiproxy/README.zh.md | 6 +- packages/host/apiproxy/package.json | 6 +- packages/host/apiproxy/src/api-proxy.ts | 106 +- .../host/apiproxy/src/api/events.schema.ts | 10 +- packages/host/apiproxy/src/api/events.ts | 8 +- packages/host/apiproxy/src/api/index.ts | 2 +- .../api/{tasks.schema.ts => jobs.schema.ts} | 14 +- .../apiproxy/src/api/{tasks.ts => jobs.ts} | 10 +- .../host/apiproxy/src/api/questions.schema.ts | 4 +- packages/host/apiproxy/src/api/questions.ts | 4 +- packages/host/apiproxy/src/api/sessions.ts | 2 +- packages/host/apiproxy/src/index.ts | 2 +- packages/host/apiproxy/src/session-export.ts | 6 +- .../tests/api-proxy-agent-preset.spec.ts | 6 +- .../apiproxy/tests/api-proxy-approval.spec.ts | 8 +- .../apiproxy/tests/api-proxy-blank.spec.ts | 6 +- .../apiproxy/tests/api-proxy-cold.spec.ts | 36 +- .../apiproxy/tests/api-proxy-config.spec.ts | 34 +- .../apiproxy/tests/api-proxy-fork.spec.ts | 6 +- ...y-tasks.spec.ts => api-proxy-jobs.spec.ts} | 90 +- .../apiproxy/tests/api-proxy-models.spec.ts | 8 +- .../tests/api-proxy-projections.spec.ts | 4 +- .../apiproxy/tests/api-proxy-question.spec.ts | 8 +- .../apiproxy/tests/api-proxy-rename.spec.ts | 4 +- .../apiproxy/tests/api-proxy-search.spec.ts | 4 +- .../tests/api-proxy-subagents.spec.ts | 2 +- .../apiproxy/tests/api-proxy-view.spec.ts | 10 +- .../tests/api-proxy-workspace.spec.ts | 10 +- .../host/apiproxy/tests/rpc-schemas.spec.ts | 16 +- .../apiproxy/tests/session-export.spec.ts | 4 +- packages/host/apiproxy/tsconfig.json | 6 +- .../directory-picker-auto/README.i18n.yaml | 4 +- packages/host/directory-picker-auto/README.md | 2 +- .../host/directory-picker-auto/README.zh.md | 2 +- .../host/directory-picker-auto/package.json | 4 +- .../host/directory-picker-auto/src/index.ts | 12 +- .../tests/loader-composition.spec.ts | 2 +- .../host/directory-picker-auto/tsconfig.json | 2 +- .../directory-picker-browse/tsconfig.json | 2 +- .../tests/built-worker.e2e.ts | 2 +- .../directory-picker-native/tsconfig.json | 2 +- .../directory-picker-native/tsdown.config.ts | 2 +- packages/host/directory-picker/tsconfig.json | 2 +- .../host/frontend-static/README.i18n.yaml | 4 +- packages/host/frontend-static/README.md | 2 +- packages/host/frontend-static/README.zh.md | 2 +- packages/host/frontend-static/package.json | 2 +- packages/host/frontend-static/src/index.ts | 12 +- .../host/frontend-static/src/invariant.ts | 8 +- .../tests/frontend-static.spec.ts | 6 +- packages/host/frontend-static/tsconfig.json | 2 +- .../host/plugin-inventory/README.i18n.yaml | 4 +- packages/host/plugin-inventory/README.md | 4 +- packages/host/plugin-inventory/README.zh.md | 4 +- packages/host/plugin-inventory/package.json | 4 +- packages/host/plugin-inventory/src/index.ts | 8 +- .../plugin-inventory/tests/invariant.spec.ts | 4 +- .../plugin-inventory/tests/inventory.spec.ts | 14 +- packages/host/plugin-inventory/tsconfig.json | 4 +- packages/host/webserver/README.i18n.yaml | 4 +- packages/host/webserver/README.md | 2 +- packages/host/webserver/README.zh.md | 2 +- packages/host/webserver/src/index.ts | 12 +- packages/host/webserver/src/invariant.ts | 4 +- .../host/webserver/tests/webserver.spec.ts | 4 +- packages/host/webserver/tsconfig.json | 2 +- packages/{pty => identity}/README.i18n.yaml | 6 +- packages/identity/README.md | 9 + packages/identity/README.zh.md | 9 + .../anonymous-user-id/README.i18n.yaml | 6 + .../anonymous-user-id}/README.md | 6 +- .../anonymous-user-id}/README.zh.md | 6 +- .../anonymous-user-id}/package.json | 8 +- .../anonymous-user-id}/src/index.ts | 10 +- .../anonymous-user-id}/src/invariant.ts | 8 +- .../tests/anonymous-user-id.spec.ts} | 20 +- .../tests/invariant.spec.ts | 6 +- .../anonymous-user-id}/tsconfig.json | 4 +- packages/interaction/README.i18n.yaml | 4 +- packages/interaction/README.md | 6 +- packages/interaction/README.zh.md | 6 +- packages/interaction/commands/package.json | 4 +- packages/interaction/commands/src/index.ts | 8 +- .../commands/tests/commands.spec.ts | 6 +- .../commands/tests/invariant.spec.ts | 4 +- packages/interaction/commands/tsconfig.json | 4 +- .../README.i18n.yaml | 6 +- .../interaction/permission-presets/README.md | 28 + .../permission-presets/README.zh.md | 28 + .../package.json | 10 +- .../src/client.ts | 2 +- .../src/index.ts | 28 +- .../src/invariant.ts | 10 +- .../src/types.ts | 2 +- .../tests/invariant.spec.ts | 10 +- .../tests/permission-presets.spec.ts} | 88 +- .../tests/projection.spec.ts | 18 +- .../tsconfig.json | 4 +- packages/interaction/permission/README.md | 28 - packages/interaction/permission/README.zh.md | 28 - .../tool-ask-user/README.i18n.yaml | 4 +- packages/interaction/tool-ask-user/README.md | 6 +- .../interaction/tool-ask-user/README.zh.md | 4 +- .../interaction/tool-ask-user/package.json | 6 +- .../interaction/tool-ask-user/src/index.ts | 8 +- .../tool-ask-user/tests/tool-ask-user.spec.ts | 38 +- .../interaction/tool-ask-user/tsconfig.json | 4 +- .../user-approval/tests/invariant.spec.ts | 8 +- .../interaction/user-approval/tsconfig.json | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 16 +- .../README.zh.md | 16 +- .../package.json | 6 +- .../src/index.ts | 46 +- .../src/invariant.ts | 8 +- .../src/types.ts | 4 +- .../tests/user-questions.spec.ts} | 104 +- .../tsconfig.json | 2 +- packages/{bash => jobs}/README.i18n.yaml | 6 +- packages/jobs/README.md | 15 + packages/jobs/README.zh.md | 15 + .../jobs-local}/README.i18n.yaml | 6 +- packages/jobs/jobs-local/README.md | 34 + .../jobs-local}/README.zh.md | 12 +- .../jobs-local}/package.json | 10 +- .../jobs-local}/src/index.ts | 316 +-- .../jobs-local}/src/invariant.ts | 12 +- .../jobs-local/tests/jobs.spec.ts} | 642 +++---- .../tests/loader-composition.spec.ts | 22 +- .../jobs-local}/tsconfig.json | 4 +- .../{bash/bash => jobs/jobs}/README.i18n.yaml | 6 +- packages/jobs/jobs/README.md | 40 + .../{tasks/tasks => jobs/jobs}/README.zh.md | 16 +- .../{tasks/tasks => jobs/jobs}/package.json | 6 +- .../{tasks/tasks => jobs/jobs}/src/brand.ts | 16 +- .../{tasks/tasks => jobs/jobs}/src/index.ts | 112 +- .../tasks => jobs/jobs}/src/invariant.ts | 30 +- .../{tasks/tasks => jobs/jobs}/src/types.ts | 92 +- .../jobs}/tests/invariant.spec.ts | 52 +- packages/jobs/jobs/tests/service.spec.ts | 96 + .../{tasks/tasks => jobs/jobs}/tsconfig.json | 2 +- .../tool-jobs}/README.i18n.yaml | 6 +- packages/jobs/tool-jobs/README.md | 96 + .../tool-jobs}/README.zh.md | 24 +- .../tool-jobs}/package.json | 16 +- .../tool-jobs}/src/index.ts | 156 +- .../tool-jobs}/src/invariant.ts | 8 +- .../tool-jobs/tests/tool-jobs.spec.ts} | 346 ++-- .../tool-jobs}/tsconfig.json | 6 +- packages/llm/llm-deepseek/README.i18n.yaml | 4 +- packages/llm/llm-deepseek/README.md | 6 +- packages/llm/llm-deepseek/README.zh.md | 6 +- packages/llm/llm-deepseek/package.json | 8 +- packages/llm/llm-deepseek/src/adapter.ts | 2 +- packages/llm/llm-deepseek/src/index.ts | 10 +- .../llm/llm-deepseek/tests/adapter.e2e.ts | 10 +- .../llm/llm-deepseek/tests/adapter.spec.ts | 58 +- .../llm-deepseek/tests/dynamic-config.spec.ts | 18 +- .../tests/loader-composition.spec.ts | 20 +- packages/llm/llm-deepseek/tsconfig.json | 6 +- packages/llm/llm-pi-ai/README.i18n.yaml | 4 +- packages/llm/llm-pi-ai/README.md | 2 +- packages/llm/llm-pi-ai/README.zh.md | 2 +- packages/llm/llm-pi-ai/package.json | 4 +- packages/llm/llm-pi-ai/src/index.ts | 4 +- packages/llm/llm-pi-ai/tests/adapter.e2e.ts | 6 +- packages/llm/llm-pi-ai/tests/adapter.spec.ts | 42 +- packages/llm/llm-pi-ai/tests/catalog.spec.ts | 10 +- .../llm/llm-pi-ai/tests/discovery.spec.ts | 10 +- .../llm-pi-ai/tests/dynamic-config.spec.ts | 12 +- .../tests/loader-composition.spec.ts | 18 +- .../llm/llm-pi-ai/tests/provider-apis.e2e.ts | 4 +- packages/llm/llm-pi-ai/tsconfig.json | 4 +- .../llm/llm-retry/tests/invariant.spec.ts | 10 +- .../tests/loader-composition.spec.ts | 8 +- .../llm/llm-retry/tests/persistence.spec.ts | 8 +- packages/llm/llm-retry/tests/retry.spec.ts | 8 +- packages/llm/llm-retry/tsconfig.json | 2 +- packages/llm/llm/README.i18n.yaml | 4 +- packages/llm/llm/README.md | 8 +- packages/llm/llm/README.zh.md | 8 +- packages/llm/llm/src/index.ts | 20 +- packages/llm/llm/src/message.ts | 2 +- packages/llm/llm/src/types.ts | 2 +- packages/llm/llm/tests/invariant.spec.ts | 10 +- packages/llm/llm/tests/service.spec.ts | 94 +- packages/llm/llm/tests/topology.spec.ts | 4 +- packages/llm/llm/tsconfig.json | 2 +- packages/llm/token-meter/README.i18n.yaml | 4 +- packages/llm/token-meter/README.md | 8 +- packages/llm/token-meter/README.zh.md | 8 +- packages/llm/token-meter/package.json | 4 +- packages/llm/token-meter/src/index.ts | 6 +- .../llm/token-meter/src/surface-projection.ts | 8 +- .../context-breakdown-projection.spec.ts | 16 +- .../llm/token-meter/tests/token-meter.spec.ts | 22 +- .../tests/token-usage-projection.spec.ts | 14 +- packages/llm/token-meter/tsconfig.json | 4 +- packages/lsp/README.i18n.yaml | 4 +- packages/lsp/README.md | 2 +- packages/lsp/README.zh.md | 2 +- .../{lsp-local => lsp-stdio}/README.i18n.yaml | 6 +- .../lsp/{lsp-local => lsp-stdio}/README.md | 2 +- .../lsp/{lsp-local => lsp-stdio}/README.zh.md | 2 +- .../lsp/{lsp-local => lsp-stdio}/package.json | 4 +- .../lsp/{lsp-local => lsp-stdio}/src/abort.ts | 2 +- .../src/connection.ts | 4 +- .../{lsp-local => lsp-stdio}/src/framing.ts | 2 +- .../lsp/{lsp-local => lsp-stdio}/src/host.ts | 0 .../lsp/{lsp-local => lsp-stdio}/src/index.ts | 24 +- .../{lsp-local => lsp-stdio}/src/instance.ts | 2 +- .../{lsp-local => lsp-stdio}/src/invariant.ts | 8 +- .../{lsp-local => lsp-stdio}/src/protocol.ts | 2 +- .../{lsp-local => lsp-stdio}/src/translate.ts | 2 +- .../tests/built-lib.e2e.ts | 8 +- .../tests/connection.spec.ts | 4 +- .../tests/fixture-server.ts | 2 +- .../tests/framing.spec.ts | 2 +- .../tests/host.spec.ts | 2 +- .../tests/instance.spec.ts | 8 +- .../tests/lifecycle.spec.ts | 24 +- .../tests/provider.spec.ts | 38 +- .../tests/translate.spec.ts | 4 +- .../tests/typescript-server.e2e.ts | 8 +- .../{lsp-local => lsp-stdio}/tsconfig.json | 2 +- packages/lsp/lsp/README.i18n.yaml | 4 +- packages/lsp/lsp/README.md | 2 +- packages/lsp/lsp/README.zh.md | 2 +- packages/lsp/lsp/tsconfig.json | 2 +- packages/lsp/tool-lsp/README.i18n.yaml | 4 +- packages/lsp/tool-lsp/README.md | 2 +- packages/lsp/tool-lsp/README.zh.md | 2 +- packages/lsp/tool-lsp/package.json | 4 +- packages/lsp/tool-lsp/src/index.ts | 2 +- .../lsp/tool-lsp/tests/integration.spec.ts | 12 +- packages/lsp/tool-lsp/tests/tool-lsp.spec.ts | 4 +- packages/lsp/tool-lsp/tsconfig.json | 2 +- packages/mcp/mcp-client/src/tools.ts | 10 +- packages/mcp/mcp-client/tests/apply.spec.ts | 8 +- .../mcp/mcp-client/tests/mcp-client.e2e.ts | 4 +- .../mcp/mcp-client/tests/mcp-client.spec.ts | 4 +- .../mcp/mcp-client/tests/reconnect.spec.ts | 4 +- packages/mcp/mcp-client/tsconfig.json | 2 +- packages/plan/plan-mode/README.i18n.yaml | 4 +- packages/plan/plan-mode/README.md | 4 +- packages/plan/plan-mode/README.zh.md | 4 +- packages/plan/plan-mode/package.json | 4 +- packages/plan/plan-mode/src/index.ts | 14 +- .../plan/plan-mode/tests/integration.spec.ts | 12 +- .../plan/plan-mode/tests/invariant.spec.ts | 10 +- .../plan/plan-mode/tests/plan-mode.spec.ts | 102 +- .../plan/plan-mode/tests/projection.spec.ts | 14 +- packages/plan/plan-mode/tsconfig.json | 4 +- .../preset/agent-presets/README.i18n.yaml | 4 +- packages/preset/agent-presets/README.md | 4 +- packages/preset/agent-presets/README.zh.md | 4 +- packages/preset/agent-presets/package.json | 6 +- .../preset/agent-presets/src/authoring.ts | 2 +- .../preset/agent-presets/src/discovery.ts | 4 +- packages/preset/agent-presets/src/index.ts | 6 +- .../agent-presets/tests/invariant.spec.ts | 12 +- .../preset/agent-presets/tests/mount.spec.ts | 16 +- .../agent-presets/tests/settings.spec.ts | 12 +- .../agent-presets/tests/user-root.spec.ts | 2 +- packages/preset/agent-presets/tsconfig.json | 4 +- packages/preset/persona/tsconfig.json | 2 +- packages/pty/README.md | 15 - packages/pty/README.zh.md | 15 - packages/pty/pty-local/README.i18n.yaml | 6 - .../pty/tool-bash-persistent/README.i18n.yaml | 6 - packages/pty/tool-pty/README.i18n.yaml | 6 - packages/pty/tool-pty/README.md | 71 - packages/pty/tool-pty/README.zh.md | 71 - .../invariants/README.i18n.yaml | 6 + .../invariants/README.md | 14 +- .../invariants/README.zh.md | 14 +- .../invariants/package.json | 2 +- .../invariants/src/index.ts | 6 +- .../invariants/src/invariant.ts | 0 .../invariants/tests/service.spec.ts | 14 +- .../invariants/tsconfig.json | 0 .../sandbox/sandbox-local/README.i18n.yaml | 4 +- packages/sandbox/sandbox-local/README.md | 4 +- packages/sandbox/sandbox-local/README.zh.md | 4 +- .../sandbox-local/tests/packed-install.e2e.ts | 4 +- packages/sandbox/sandbox-local/tsconfig.json | 2 +- .../sandbox-policy/tests/invariant.spec.ts | 6 +- packages/sandbox/sandbox-policy/tsconfig.json | 2 +- .../sandbox-windows-acl/README.i18n.yaml | 4 +- .../sandbox/sandbox-windows-acl/README.md | 2 +- .../sandbox/sandbox-windows-acl/README.zh.md | 2 +- .../sandbox/sandbox-windows-acl/tsconfig.json | 2 +- packages/sandbox/sandbox/README.i18n.yaml | 4 +- packages/sandbox/sandbox/README.md | 6 +- packages/sandbox/sandbox/README.zh.md | 6 +- packages/sandbox/sandbox/tsconfig.json | 2 +- packages/schedule/README.i18n.yaml | 4 +- packages/schedule/README.md | 2 +- packages/schedule/README.zh.md | 2 +- .../README.i18n.yaml | 6 +- .../{tool-schedule => schedule}/README.md | 4 +- .../{tool-schedule => schedule}/README.zh.md | 4 +- .../{tool-schedule => schedule}/package.json | 4 +- .../{tool-schedule => schedule}/src/domain.ts | 2 +- .../{tool-schedule => schedule}/src/index.ts | 32 +- .../src/invariant.ts | 4 +- .../src/persistence.ts | 0 .../src/runtime.ts | 34 +- .../{tool-schedule => schedule}/src/tools.ts | 6 +- .../src/transaction.ts | 0 .../{tool-schedule => schedule}/src/types.ts | 2 +- .../tests/domain.spec.ts | 0 .../tests/invariant.spec.ts | 8 +- .../tests/jsonl-restart.spec.ts | 6 +- .../tests/plugin.spec.ts | 2 +- .../tests/recurrence.spec.ts | 0 .../tests/runtime.spec.ts | 258 +-- .../tests/tools.spec.ts | 4 +- .../{tool-schedule => schedule}/tsconfig.json | 2 +- .../tsdown.config.ts | 0 packages/sdk/client/tsconfig.json | 2 +- packages/sdk/protocol/README.i18n.yaml | 4 +- packages/sdk/protocol/README.md | 8 +- packages/sdk/protocol/README.zh.md | 8 +- packages/sdk/protocol/src/index.ts | 2 +- packages/sdk/protocol/src/types.ts | 4 +- packages/sdk/protocol/tsconfig.json | 2 +- packages/sdk/server/README.i18n.yaml | 4 +- packages/sdk/server/README.md | 4 +- packages/sdk/server/README.zh.md | 4 +- packages/sdk/server/package.json | 2 +- packages/sdk/server/src/index.ts | 12 +- packages/sdk/server/src/invariant.ts | 8 +- packages/sdk/server/src/server.ts | 16 +- .../server/tests/built-scope-carrier.e2e.ts | 16 +- .../sdk/server/tests/plugin-apply.spec.ts | 6 +- .../sdk/server/tests/plugin-shape.spec.ts | 4 +- packages/sdk/server/tests/server.spec.ts | 54 +- packages/sdk/server/tsconfig.json | 2 +- .../tool-cordis/README.i18n.yaml | 6 - packages/session-query/README.i18n.yaml | 4 +- packages/session-query/README.md | 2 +- packages/session-query/README.zh.md | 2 +- .../session-export/tsdown.config.ts | 3 - .../README.i18n.yaml | 6 +- .../README.md | 8 +- .../README.zh.md | 8 +- .../package.json | 10 +- .../src/client/Dialog.tsx | 18 +- .../src/client/HeaderAction.module.css | 0 .../src/client/HeaderAction.tsx | 10 +- .../src/client/controller.ts | 18 +- .../src/client/index.ts | 34 +- .../src/client/locales.ts | 4 +- .../src/css-modules.d.ts | 0 .../src/index.ts | 4 +- .../src/invariant.ts | 4 +- .../tests/client-apply.client.spec.tsx | 34 +- .../tests/command.client.spec.ts | 4 +- .../tests/controller.client.spec.ts | 22 +- .../tests/dialog.client.spec.tsx | 18 +- .../tests/header-action.client.spec.tsx | 30 +- .../tests/invariant.client.spec.ts | 4 +- .../tests/loader-composition.client.spec.ts | 12 +- .../tsconfig.json | 4 +- .../session-log-download/tsdown.config.ts | 3 + .../session-query-sqlite/README.i18n.yaml | 4 +- .../session-query-sqlite/README.md | 2 +- .../session-query-sqlite/README.zh.md | 2 +- .../session-query-sqlite/src/index.ts | 6 +- .../tests/load-path.e2e.ts | 8 +- .../session-query-sqlite/tests/sqlite.spec.ts | 94 +- .../session-query-sqlite/tsconfig.json | 2 +- .../session-query/README.i18n.yaml | 4 +- .../session-query/session-query/README.md | 4 +- .../session-query/session-query/README.zh.md | 4 +- .../session-query/session-query/src/index.ts | 6 +- .../tests/search-helpers.spec.ts | 6 +- .../session-query/tests/session-query.spec.ts | 18 +- .../session-query/tests/test-service.ts | 4 +- .../session-query/tests/tracing.spec.ts | 4 +- .../session-query/session-query/tsconfig.json | 2 +- .../tool-session-query/package.json | 2 +- .../tests/sqlite-integration.spec.ts | 18 +- .../tests/tool-session-query.spec.ts | 10 +- .../tool-session-query/tsconfig.json | 2 +- packages/session/README.i18n.yaml | 4 +- packages/session/README.md | 8 +- packages/session/README.zh.md | 6 +- .../tests/crash-recovery.e2e.ts | 4 +- .../tests/fixtures/crash-child.ts | 4 +- .../tests/session-checkpoint-policy.spec.ts | 12 +- .../session-checkpoint-policy/tsconfig.json | 2 +- .../session-persistence-jsonl/src/index.ts | 4 +- .../tests/jsonl.spec.ts | 62 +- .../tests/zstd.spec.ts | 18 +- .../session-persistence-jsonl/tsconfig.json | 2 +- .../session-persistence-sqlite/src/index.ts | 4 +- .../tests/sqlite.spec.ts | 44 +- .../session-persistence-sqlite/tsconfig.json | 2 +- .../session-persistence/README.i18n.yaml | 4 +- .../session/session-persistence/README.md | 2 +- .../session/session-persistence/README.zh.md | 2 +- .../session/session-persistence/tsconfig.json | 2 +- .../session-projection-cache/tsconfig.json | 2 +- .../session/session-projection/tsconfig.json | 2 +- packages/session/session-stats/tsconfig.json | 2 +- .../session-telemetry-otel/README.i18n.yaml | 4 +- .../session/session-telemetry-otel/README.md | 16 +- .../session-telemetry-otel/README.zh.md | 16 +- .../session-telemetry-otel/package.json | 4 +- .../session-telemetry-otel/src/index.ts | 66 +- .../tests/loader-composition.e2e.ts | 4 +- .../session-telemetry-otel/tests/otel.spec.ts | 114 +- .../session-telemetry-otel/tsconfig.json | 4 +- .../session-telemetry/README.i18n.yaml | 4 +- packages/session/session-telemetry/README.md | 12 +- .../session/session-telemetry/README.zh.md | 12 +- .../session/session-telemetry/package.json | 2 +- .../session-telemetry/src/coordinator.ts | 24 +- .../session/session-telemetry/src/index.ts | 48 +- .../session-telemetry/tests/redact.spec.ts | 32 +- .../session-telemetry/tests/telemetry.spec.ts | 56 +- .../session/session-telemetry/tsconfig.json | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 4 +- .../README.zh.md | 4 +- .../package.json | 4 +- .../src/index.ts | 8 +- .../src/invariant.ts | 8 +- .../tests/provider.spec.ts | 6 +- .../tsconfig.json | 2 +- .../README.i18n.yaml | 6 - .../README.i18n.yaml | 6 +- .../README.md | 4 +- .../README.zh.md | 4 +- .../package.json | 4 +- .../src/index.ts | 8 +- .../src/invariant.ts | 8 +- .../tests/loader-composition.spec.ts | 12 +- .../tests/provider.e2e.ts | 10 +- .../tests/provider.spec.ts | 10 +- .../tsconfig.json | 2 +- .../session-title-llm/tests/llm.spec.ts | 12 +- .../session/session-title-llm/tsconfig.json | 2 +- .../session/session-title/README.i18n.yaml | 4 +- packages/session/session-title/README.md | 4 +- packages/session/session-title/README.zh.md | 2 +- packages/session/session-title/src/index.ts | 6 +- .../session/session-title/src/normalize.ts | 2 +- .../session-title/tests/invariant.spec.ts | 4 +- .../session-title/tests/persistence.spec.ts | 12 +- .../session-title/tests/provider.spec.ts | 30 +- .../session-title/tests/rename.spec.ts | 4 +- .../tests/service-contracts.spec.ts | 22 +- packages/session/session-title/tsconfig.json | 2 +- packages/settings/README.i18n.yaml | 4 +- packages/settings/README.md | 2 +- packages/settings/README.zh.md | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 2 +- .../README.zh.md | 2 +- .../package.json | 8 +- .../src/index.ts | 24 +- .../src/invariant.ts | 8 +- .../tests/concurrency.spec.ts | 6 +- .../tests/loader-composition.spec.ts | 8 +- .../tests/local.spec.ts | 6 +- .../tests/lock-race.spec.ts | 8 +- .../tests/watcher.spec.ts | 8 +- .../tsconfig.json | 4 +- packages/settings/settings/src/index.ts | 8 +- .../settings/settings/tests/invariant.spec.ts | 4 +- packages/settings/settings/tests/memory.ts | 6 +- .../settings/settings/tests/settings.spec.ts | 6 +- packages/settings/settings/tsconfig.json | 2 +- packages/{tasks => shell}/README.i18n.yaml | 6 +- packages/{bash => shell}/README.md | 16 +- packages/{bash => shell}/README.zh.md | 14 +- packages/shell/bash-local/README.i18n.yaml | 6 + packages/{bash => shell}/bash-local/README.md | 8 +- .../{bash => shell}/bash-local/README.zh.md | 8 +- .../{bash => shell}/bash-local/package.json | 6 +- .../{bash => shell}/bash-local/src/index.ts | 28 +- .../bash-local/src/invariant.ts | 0 .../bash-local/tests/executor.spec.ts | 26 +- .../bash-local/tests/settings.spec.ts | 30 +- .../{bash => shell}/bash-local/tsconfig.json | 4 +- packages/shell/bash-sandbox/README.i18n.yaml | 6 + .../{bash => shell}/bash-sandbox/README.md | 10 +- .../{bash => shell}/bash-sandbox/README.zh.md | 10 +- .../{bash => shell}/bash-sandbox/package.json | 6 +- .../bash-sandbox/src/helpers.ts | 4 +- .../{bash => shell}/bash-sandbox/src/index.ts | 20 +- .../bash-sandbox/src/invariant.ts | 0 .../bash-sandbox/tests/bwrap.e2e.ts | 8 +- .../bash-sandbox/tests/landlock.e2e.ts | 8 +- .../tests/partial-landlock.spec.ts | 10 +- .../bash-sandbox/tests/sandbox.spec.ts | 24 +- .../bash-sandbox/tests/seatbelt.e2e.ts | 8 +- .../bash-sandbox/tsconfig.json | 6 +- packages/shell/pwsh-local/README.i18n.yaml | 6 + packages/{bash => shell}/pwsh-local/README.md | 10 +- .../{bash => shell}/pwsh-local/README.zh.md | 8 +- .../{bash => shell}/pwsh-local/package.json | 6 +- .../{bash => shell}/pwsh-local/src/index.ts | 28 +- .../pwsh-local/src/invariant.ts | 0 .../{bash => shell}/pwsh-local/src/resolve.ts | 0 .../pwsh-local/tests/executor.spec.ts | 34 +- .../pwsh-local/tests/settings.spec.ts | 26 +- .../{bash => shell}/pwsh-local/tsconfig.json | 4 +- packages/shell/pwsh-sandbox/README.i18n.yaml | 6 + .../{bash => shell}/pwsh-sandbox/README.md | 2 +- .../{bash => shell}/pwsh-sandbox/README.zh.md | 2 +- .../{bash => shell}/pwsh-sandbox/package.json | 6 +- .../pwsh-sandbox/src/helpers.ts | 4 +- .../{bash => shell}/pwsh-sandbox/src/index.ts | 20 +- .../pwsh-sandbox/src/invariant.ts | 0 .../pwsh-sandbox/tests/acl.e2e.ts | 6 +- .../pwsh-sandbox/tests/sandbox.spec.ts | 18 +- .../pwsh-sandbox/tsconfig.json | 6 +- packages/shell/shell-env/README.i18n.yaml | 6 + packages/shell/shell-env/README.md | 51 + packages/shell/shell-env/README.zh.md | 51 + .../bash-env => shell/shell-env}/package.json | 12 +- .../bash-env => shell/shell-env}/src/index.ts | 32 +- .../shell-env}/src/invariant.ts | 8 +- .../shell-env/tests/shell-env.spec.ts} | 42 +- .../shell-env}/tsconfig.json | 6 +- packages/shell/shell/README.i18n.yaml | 6 + packages/{bash/bash => shell/shell}/README.md | 28 +- packages/shell/shell/README.zh.md | 53 + .../{bash/bash => shell/shell}/package.json | 6 +- .../{bash/bash => shell/shell}/src/index.ts | 48 +- .../bash => shell/shell}/src/invariant.ts | 6 +- .../{bash/bash => shell/shell}/src/render.ts | 4 +- .../{bash/bash => shell/shell}/src/types.ts | 44 +- .../bash => shell/shell}/tests/render.spec.ts | 0 .../shell}/tests/service.spec.ts | 34 +- .../{bash/bash => shell/shell}/tsconfig.json | 2 +- .../tool-bash-persistent/README.i18n.yaml | 6 + .../tool-bash-persistent/README.md | 2 +- .../tool-bash-persistent/README.zh.md | 2 +- .../tool-bash-persistent/package.json | 8 +- .../tool-bash-persistent/src/index.ts | 38 +- .../tool-bash-persistent/src/invariant.ts | 0 .../tests/loader-composition.spec.ts | 20 +- .../tool-bash-persistent/tests/tools.spec.ts | 56 +- .../tool-bash-persistent/tsconfig.json | 4 +- packages/shell/tool-bash/README.i18n.yaml | 6 + packages/{bash => shell}/tool-bash/README.md | 30 +- .../{bash => shell}/tool-bash/README.zh.md | 28 +- .../{bash => shell}/tool-bash/package.json | 20 +- .../tool-bash/src/background.ts | 8 +- .../{bash => shell}/tool-bash/src/index.ts | 48 +- .../tool-bash/src/invariant.ts | 0 .../{bash => shell}/tool-bash/src/render.ts | 16 +- .../tool-bash/tests/integration.spec.ts | 34 +- .../tool-bash/tests/tools.spec.ts | 176 +- .../{bash => shell}/tool-bash/tsconfig.json | 8 +- packages/shell/tool-pwsh/README.i18n.yaml | 6 + packages/{bash => shell}/tool-pwsh/README.md | 26 +- .../{bash => shell}/tool-pwsh/README.zh.md | 22 +- .../{bash => shell}/tool-pwsh/package.json | 18 +- .../tool-pwsh/src/background.ts | 8 +- .../{bash => shell}/tool-pwsh/src/index.ts | 56 +- .../tool-pwsh/src/invariant.ts | 0 .../{bash => shell}/tool-pwsh/src/render.ts | 10 +- .../tool-pwsh/tests/integration.spec.ts | 26 +- .../tool-pwsh/tests/loader.spec.ts | 4 +- .../tool-pwsh/tests/tools.spec.ts | 138 +- .../{bash => shell}/tool-pwsh/tsconfig.json | 10 +- packages/skill/README.i18n.yaml | 4 +- packages/skill/README.md | 2 +- packages/skill/README.zh.md | 2 +- .../skill-badge/tests/skill-badge.spec.ts | 4 +- packages/skill/skill-badge/tsconfig.json | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 6 +- .../README.zh.md | 6 +- .../package.json | 8 +- .../src/index.ts | 28 +- .../src/invariant.ts | 8 +- .../tests/skill-filesystem-watcher.spec.ts} | 56 +- .../tests/skill-filesystem.spec.ts} | 84 +- .../tsconfig.json | 4 +- packages/skill/skill/README.i18n.yaml | 4 +- packages/skill/skill/README.md | 4 +- packages/skill/skill/README.zh.md | 4 +- packages/skill/skill/src/index.ts | 8 +- packages/skill/skill/tests/skill.spec.ts | 86 +- packages/skill/skill/tsconfig.json | 2 +- packages/skill/tool-skill/package.json | 2 +- .../skill/tool-skill/tests/tool-skill.spec.ts | 26 +- packages/skill/tool-skill/tsconfig.json | 2 +- packages/spill/spill-local/tsconfig.json | 2 +- packages/spill/spill-policy/README.i18n.yaml | 4 +- packages/spill/spill-policy/README.md | 4 +- packages/spill/spill-policy/README.zh.md | 4 +- packages/spill/spill-policy/package.json | 6 +- packages/spill/spill-policy/src/index.ts | 6 +- .../spill-policy/tests/spill-policy.spec.ts | 26 +- packages/spill/spill-policy/tsconfig.json | 4 +- packages/spill/spill/README.i18n.yaml | 4 +- packages/spill/spill/README.md | 4 +- packages/spill/spill/README.zh.md | 4 +- packages/spill/spill/src/index.ts | 2 +- packages/spill/spill/tsconfig.json | 2 +- .../storage-domain/tests/invariant.spec.ts | 4 +- packages/storage/storage-domain/tsconfig.json | 2 +- .../storage-json/tests/json-backend.spec.ts | 4 +- packages/storage/storage-json/tsconfig.json | 2 +- .../storage-sqlite/tests/invariant.spec.ts | 4 +- packages/storage/storage-sqlite/tsconfig.json | 2 +- packages/storage/storage/tsconfig.json | 2 +- packages/subagent/README.i18n.yaml | 4 +- packages/subagent/README.md | 6 +- packages/subagent/README.zh.md | 6 +- .../subagent-acp/tests/subagent-acp.e2e.ts | 12 +- .../subagent-acp/tests/subagent-acp.spec.ts | 52 +- packages/subagent/subagent-acp/tsconfig.json | 4 +- .../tests/real-deepseek.e2e.ts | 8 +- .../tests/real-product.spec.ts | 8 +- .../tests/subagent-claude-code.spec.ts | 12 +- .../subagent-claude-code/tsconfig.json | 2 +- .../subagent-codex/tests/real-deepseek.e2e.ts | 8 +- .../subagent-codex/tests/real-product.spec.ts | 8 +- .../tests/subagent-codex.spec.ts | 16 +- .../subagent/subagent-codex/tsconfig.json | 2 +- .../subagent/subagent-dsh-sdk/src/index.ts | 4 +- .../tests/subagent-dsh-sdk.spec.ts | 14 +- .../subagent/subagent-dsh-sdk/tsconfig.json | 4 +- .../README.i18n.yaml | 6 +- .../README.md | 6 +- .../README.zh.md | 6 +- .../package.json | 10 +- .../src/index.ts | 12 +- .../src/invariant.ts | 8 +- .../tests/multi-subagent.spec.ts | 10 +- .../tests/subagent-fork-in-process.spec.ts} | 18 +- .../tsconfig.json | 4 +- .../README.i18n.yaml | 6 +- .../README.md | 2 +- .../README.zh.md | 2 +- .../package.json | 4 +- .../src/index.ts | 2 +- .../src/invariant.ts | 8 +- .../src/structured.ts | 4 +- .../tests/fixtures/plugins/preset-tool.js | 0 .../fixtures/presets/coding/agent.cordis.yml | 0 .../presets/reviewing/agent.cordis.yml | 0 .../tests/inheritance.spec.ts | 0 .../tests/preset-inheritance.spec.ts | 0 .../tests/structured.spec.ts | 8 +- .../tests/subagent-in-process-driver.spec.ts} | 8 +- .../tsconfig.json | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 4 +- .../README.zh.md | 4 +- .../package.json | 8 +- .../src/index.ts | 10 +- .../src/invariant.ts | 8 +- .../tests/harness.ts | 10 +- .../tests/spawn-in-process.e2e.ts} | 0 .../tests/subagent-spawn-in-process.spec.ts} | 24 +- .../tsconfig.json | 4 +- packages/subagent/subagent/README.i18n.yaml | 4 +- packages/subagent/subagent/README.md | 6 +- packages/subagent/subagent/README.zh.md | 4 +- packages/subagent/subagent/package.json | 6 +- .../subagent/subagent/src/continuation.ts | 2 +- packages/subagent/subagent/src/index.ts | 16 +- .../subagent/subagent/src/list-children.ts | 4 +- .../subagent/subagent/src/run-settlement.ts | 12 +- packages/subagent/subagent/src/types.ts | 2 +- .../tests/continuation-inheritance.spec.ts | 8 +- .../subagent/tests/continuation.spec.ts | 22 +- .../subagent/subagent/tests/invariant.spec.ts | 8 +- .../subagent/tests/list-children.spec.ts | 18 +- .../subagent/subagent/tests/service.spec.ts | 10 +- .../subagent/tests/timing-projection.spec.ts | 4 +- packages/subagent/subagent/tsconfig.json | 4 +- .../tool-subagent-control/package.json | 2 +- .../tests/list-agents.spec.ts | 8 +- .../tests/tool-subagent-control.spec.ts | 12 +- .../tool-subagent-control/tsconfig.json | 2 +- .../tool-subagent-report/package.json | 2 +- .../tests/tool-subagent-report.spec.ts | 10 +- .../tool-subagent-report/tsconfig.json | 2 +- .../subagent/tool-subagent/README.i18n.yaml | 4 +- packages/subagent/tool-subagent/README.md | 8 +- packages/subagent/tool-subagent/README.zh.md | 8 +- packages/subagent/tool-subagent/package.json | 10 +- packages/subagent/tool-subagent/src/index.ts | 24 +- .../tests/scripted-provider.spec.ts | 6 +- .../tool-subagent/tests/tool-subagent.spec.ts | 170 +- packages/subagent/tool-subagent/tsconfig.json | 4 +- packages/subprocess/README.i18n.yaml | 4 +- packages/subprocess/README.md | 2 +- packages/subprocess/README.zh.md | 2 +- .../subprocess-local/README.i18n.yaml | 4 +- .../subprocess/subprocess-local/README.md | 2 +- .../subprocess/subprocess-local/README.zh.md | 2 +- .../subprocess/subprocess-local/src/index.ts | 6 +- .../tests/fixtures/process-exit-host.ts | 4 +- .../subprocess-local/tests/local.spec.ts | 52 +- .../subprocess-local/tests/spawn.spec.ts | 6 +- .../subprocess/subprocess-local/tsconfig.json | 2 +- .../subprocess/subprocess/README.i18n.yaml | 4 +- packages/subprocess/subprocess/README.md | 4 +- packages/subprocess/subprocess/README.zh.md | 4 +- packages/subprocess/subprocess/src/index.ts | 6 +- packages/subprocess/subprocess/src/types.ts | 4 +- .../subprocess/tests/service.spec.ts | 12 +- packages/subprocess/subprocess/tsconfig.json | 2 +- packages/support/README.i18n.yaml | 6 - packages/support/invariants/README.i18n.yaml | 6 - packages/support/llm-replay/README.i18n.yaml | 6 - packages/tasks/README.md | 15 - packages/tasks/README.zh.md | 15 - packages/tasks/tasks-local/README.i18n.yaml | 6 - packages/tasks/tasks-local/README.md | 34 - packages/tasks/tasks/README.i18n.yaml | 6 - packages/tasks/tasks/README.md | 40 - packages/tasks/tasks/tests/service.spec.ts | 96 - packages/tasks/tool-tasks/README.i18n.yaml | 6 - packages/tasks/tool-tasks/README.md | 96 - .../{pty/pty => terminal}/README.i18n.yaml | 6 +- packages/terminal/README.md | 15 + packages/terminal/README.zh.md | 15 + .../terminal/terminal-bash/README.i18n.yaml | 6 + .../terminal-bash}/README.md | 10 +- .../terminal-bash}/README.zh.md | 10 +- .../terminal-bash}/package.json | 8 +- .../terminal-bash}/src/config.ts | 10 +- .../terminal-bash}/src/index.ts | 32 +- .../terminal-bash}/src/invariant.ts | 8 +- .../terminal-bash}/src/sanitize.ts | 0 .../terminal-bash}/src/session.ts | 58 +- .../terminal-bash}/tests/config.spec.ts | 6 +- .../terminal-bash}/tests/index.spec.ts | 90 +- .../terminal-bash}/tests/local.spec.ts | 70 +- .../terminal-bash}/tests/sanitize.spec.ts | 2 +- .../terminal-bash}/tests/session.spec.ts | 60 +- .../terminal-bash}/tsconfig.json | 4 +- .../terminal}/README.i18n.yaml | 6 +- .../{pty/pty => terminal/terminal}/README.md | 14 +- .../pty => terminal/terminal}/README.zh.md | 12 +- .../pty => terminal/terminal}/package.json | 4 +- .../pty => terminal/terminal}/src/index.ts | 158 +- .../terminal}/src/invariant.ts | 8 +- .../pty => terminal/terminal}/src/types.ts | 74 +- .../terminal}/tests/service.spec.ts | 246 +-- .../pty => terminal/terminal}/tsconfig.json | 2 +- .../terminal/tool-terminal/README.i18n.yaml | 6 + packages/terminal/tool-terminal/README.md | 71 + packages/terminal/tool-terminal/README.zh.md | 71 + .../tool-terminal}/package.json | 24 +- .../tool-terminal}/src/index.ts | 64 +- .../tool-terminal}/src/invariant.ts | 10 +- .../tool-terminal}/src/render.ts | 4 +- .../tests/loader-composition.spec.ts | 30 +- .../tool-terminal}/tests/render.spec.ts | 22 +- .../tool-terminal}/tests/tools.spec.ts | 78 +- .../tool-terminal}/tsconfig.json | 8 +- .../README.i18n.yaml | 6 +- packages/{support => test-support}/README.md | 6 +- .../{support => test-support}/README.zh.md | 6 +- .../acp-snapshot/README.i18n.yaml | 2 +- .../acp-snapshot/README.md | 0 .../acp-snapshot/README.zh.md | 0 .../acp-snapshot/package.json | 2 +- .../acp-snapshot/src/harness.ts | 0 .../acp-snapshot/src/index.ts | 0 .../acp-snapshot/src/invariant.ts | 0 .../acp-snapshot/src/launcher.ts | 0 .../acp-snapshot/src/normalize.ts | 0 .../acp-snapshot/src/suite.ts | 0 .../tests/fixtures/fake-acp-agent.ts | 0 .../record-suite/rec-child/behavior.json | 0 .../record-suite/rec-child/input.json | 0 .../record-suite/rec-child/session.1.jsonl | 0 .../record-suite/rec-child/session.jsonl | 0 .../rec-child/stdout.expected.jsonl | 0 .../record-suite/rec-pin/behavior.json | 0 .../fixtures/record-suite/rec-pin/input.json | 0 .../record-suite/rec-pin/session.1.jsonl | 0 .../record-suite/rec-pin/session.jsonl | 0 .../rec-pin/stdout.expected.jsonl | 0 .../rec-pin/system-prompt.expected.md | 0 .../rec-pin/tool-schemas.expected.json | 0 .../record-suite/rec-skip/behavior.json | 0 .../fixtures/record-suite/rec-skip/input.json | 0 .../rec-skip/replay.override.json | 0 .../record-suite/rec-skip/session.jsonl | 0 .../rec-skip/stdout.expected.jsonl | 0 .../suite/authored-error/behavior.json | 0 .../fixtures/suite/authored-error/input.json | 0 .../suite/authored-error/replay.override.json | 0 .../suite/authored-error/session.jsonl | 0 .../authored-error/stdout.expected.jsonl | 0 .../fixtures/suite/blocked-log/behavior.json | 0 .../fixtures/suite/blocked-log/input.json | 0 .../fixtures/suite/blocked-log/session.jsonl | 0 .../suite/blocked-log/stdout.expected.jsonl | 0 .../fixtures/suite/no-model/behavior.json | 0 .../tests/fixtures/suite/no-model/input.json | 0 .../fixtures/suite/no-model/session.jsonl | 0 .../suite/no-model/stdout.expected.jsonl | 0 .../fixtures/suite/pin-turn/behavior.json | 0 .../tests/fixtures/suite/pin-turn/input.json | 0 .../fixtures/suite/pin-turn/session.jsonl | 0 .../suite/pin-turn/stdout.expected.jsonl | 0 .../suite/pin-turn/system-prompt.expected.md | 0 .../suite/pin-turn/tool-schemas.expected.json | 0 .../fixtures/suite/plain-turn/behavior.json | 0 .../fixtures/suite/plain-turn/input.json | 0 .../fixtures/suite/plain-turn/session.1.jsonl | 0 .../fixtures/suite/plain-turn/session.jsonl | 0 .../suite/plain-turn/stdout.expected.jsonl | 0 .../plain-turn/system-prompt.1.expected.md | 0 .../plain-turn/tool-schemas.1.expected.json | 0 .../suite/plain-turn/workspace/seed.txt | 0 .../fixtures/suite/shared-pin/behavior.json | 0 .../fixtures/suite/shared-pin/input.json | 0 .../fixtures/suite/shared-pin/session.jsonl | 0 .../suite/shared-pin/stdout.expected.jsonl | 0 .../acp-snapshot/tests/harness.spec.ts | 0 .../acp-snapshot/tests/normalize.spec.ts | 0 .../acp-snapshot/tests/suite.spec.ts | 0 .../acp-snapshot/tsconfig.json | 2 +- .../agent-loop-testkit/README.i18n.yaml | 2 +- .../agent-loop-testkit/README.md | 0 .../agent-loop-testkit/README.zh.md | 0 .../agent-loop-testkit/package.json | 2 +- .../agent-loop-testkit/src/index.ts | 12 +- .../agent-loop-testkit/src/invariant.ts | 0 .../tests/agent-loop-testkit.spec.ts | 0 .../agent-loop-testkit/tsconfig.json | 2 +- .../client-runtime/README.i18n.yaml | 6 + .../client-runtime}/README.md | 4 +- .../client-runtime}/README.zh.md | 4 +- .../client-runtime}/package.json | 4 +- .../client-runtime}/src/fixtures.ts | 2 +- .../client-runtime}/src/index.ts | 22 +- .../client-runtime}/src/invariant.ts | 2 +- .../client-runtime}/src/locale-env.ts | 2 +- .../client-runtime}/src/remote.ts | 0 .../client-runtime}/src/sessions.ts | 10 +- .../client-runtime}/src/settings-scope.ts | 0 .../client-runtime}/src/snapshot.ts | 0 .../client-runtime}/src/translate.ts | 2 +- .../client-runtime}/src/workspaces.ts | 0 .../runtime.client.spec.tsx.snap | 0 .../tests/invariant.client.spec.ts | 4 +- .../tests/remote.client.spec.ts | 0 .../tests/runtime.client.spec.tsx | 2 +- .../client-runtime}/tsconfig.json | 8 +- .../client-runtime}/tsdown.config.ts | 2 +- .../llm-mock-server/README.i18n.yaml | 2 +- .../llm-mock-server/README.md | 0 .../llm-mock-server/README.zh.md | 0 .../llm-mock-server/package.json | 2 +- .../llm-mock-server/src/bin.ts | 0 .../llm-mock-server/src/cli.ts | 0 .../llm-mock-server/src/index.ts | 0 .../llm-mock-server/src/invariant.ts | 0 .../llm-mock-server/tests/cli.spec.ts | 0 .../llm-mock-server/tests/invariant.spec.ts | 4 +- .../llm-mock-server/tests/server.spec.ts | 0 .../llm-mock-server}/tsconfig.json | 2 +- .../llm-mock-server/tsdown.config.ts | 0 .../test-support/llm-replay/README.i18n.yaml | 6 + .../llm-replay/README.md | 4 +- .../llm-replay/README.zh.md | 4 +- .../llm-replay/package.json | 6 +- .../llm-replay/src/index.ts | 16 +- .../llm-replay/src/invariant.ts | 0 .../llm-replay/tests/llm-replay.spec.ts | 100 +- .../llm-replay/tsconfig.json | 4 +- .../loader-smoke/README.i18n.yaml | 2 +- .../loader-smoke/README.md | 0 .../loader-smoke/README.zh.md | 0 .../loader-smoke/package.json | 2 +- .../loader-smoke/src/agent-turn.ts | 0 .../loader-smoke/src/index.ts | 0 .../loader-smoke/src/invariant.ts | 0 .../loader-smoke/tests/agent-turn.spec.ts | 0 .../loader-smoke/tests/example-launch.spec.ts | 0 .../loader-smoke/tests/fixtures/fail.ts | 0 .../loader-smoke/tests/fixtures/hang.ts | 0 .../loader-smoke/tests/fixtures/success.ts | 0 .../loader-smoke/tests/loader-smoke.spec.ts | 0 .../loader-smoke/tsconfig.json | 2 +- packages/todo/tool-todo/package.json | 2 +- .../todo/tool-todo/tests/invariant.spec.ts | 12 +- .../tests/loader-composition.spec.ts | 4 +- .../todo/tool-todo/tests/projection.spec.ts | 8 +- .../todo/tool-todo/tests/tool-todo.spec.ts | 8 +- packages/todo/tool-todo/tsconfig.json | 2 +- packages/typert/generator/README.i18n.yaml | 4 +- packages/typert/generator/README.md | 4 +- packages/typert/generator/README.zh.md | 4 +- packages/typert/generator/src/analyzer.ts | 82 +- .../typert/generator/src/cordis-catalog.ts | 4 +- packages/typert/generator/src/emitter.ts | 18 +- packages/typert/generator/src/model.ts | 2 +- .../tests/cordis-catalog-contract.spec.ts | 4 +- .../generator/tests/cordis-catalog.spec.ts | 2 +- .../remote-model/packages/domain/src/index.ts | 12 +- .../remote-model/packages/remote/src/index.ts | 4 +- .../fixtures/remote-model/tsconfig.base.json | 2 +- .../{type-meta.d.ts => typert-protocol.d.ts} | 34 +- .../generator/tests/remote-model.spec.ts | 72 +- .../typert/generator/tests/type-model.spec.ts | 2 +- packages/typert/generator/tsconfig.json | 2 +- packages/typert/loader/tests/loader.spec.ts | 2 +- packages/typert/loader/tsconfig.json | 2 +- .../{type-meta => protocol}/README.i18n.yaml | 6 +- .../typert/{type-meta => protocol}/README.md | 20 +- .../{type-meta => protocol}/README.zh.md | 20 +- .../{type-meta => protocol}/package.json | 6 +- .../{type-meta => protocol}/src/index.ts | 120 +- .../{type-meta => protocol}/src/invariant.ts | 8 +- .../{type-meta => protocol}/src/types.ts | 180 +- .../tests/fixtures/source-launch.ts | 6 +- .../tests/protocol.spec.ts} | 56 +- .../{type-meta => protocol}/tsconfig.json | 2 +- packages/typert/registry/package.json | 2 +- packages/typert/registry/src/client/index.ts | 2 +- packages/typert/registry/src/index.ts | 10 +- packages/typert/registry/src/service.ts | 136 +- packages/typert/registry/src/types.ts | 2 +- packages/typert/registry/tests/typert.spec.ts | 22 +- packages/typert/registry/tsconfig.json | 4 +- packages/util/README.i18n.yaml | 4 +- packages/util/README.md | 4 +- packages/util/README.zh.md | 4 +- packages/util/atomic-write/README.i18n.yaml | 4 +- packages/util/atomic-write/README.md | 2 +- packages/util/atomic-write/README.zh.md | 2 +- .../util/atomic-write/tests/invariant.spec.ts | 4 +- packages/util/atomic-write/tsconfig.json | 2 +- packages/util/brand/README.i18n.yaml | 4 +- packages/util/brand/README.md | 4 +- packages/util/brand/README.zh.md | 4 +- packages/util/brand/src/index.ts | 2 +- packages/util/brand/tsconfig.json | 2 +- packages/util/environment/README.i18n.yaml | 6 - packages/util/home-paths/README.i18n.yaml | 6 + packages/util/{paths => home-paths}/README.md | 2 +- .../util/{paths => home-paths}/README.zh.md | 2 +- .../util/{paths => home-paths}/package.json | 4 +- .../util/{paths => home-paths}/src/index.ts | 2 +- .../src/invariant.ts | 8 +- .../tests/home-paths.spec.ts} | 2 +- .../{retention => home-paths}/tsconfig.json | 2 +- .../util/launch-environment/README.i18n.yaml | 6 + .../README.md | 8 +- .../README.zh.md | 8 +- .../package.json | 4 +- .../src/index.ts | 40 +- .../src/invariant.ts | 8 +- .../tests/launch-environment.spec.ts} | 20 +- .../tsconfig.json | 2 +- packages/util/native-command/README.i18n.yaml | 4 +- packages/util/native-command/README.md | 2 +- packages/util/native-command/README.zh.md | 2 +- packages/util/native-command/tsconfig.json | 2 +- .../util/output-retention/README.i18n.yaml | 6 + .../{retention => output-retention}/README.md | 8 +- .../README.zh.md | 6 +- .../package.json | 4 +- .../src/index.ts | 2 +- .../src/invariant.ts | 8 +- .../tests/output-retention.spec.ts} | 2 +- .../output-retention}/tsconfig.json | 2 +- packages/util/paths/README.i18n.yaml | 6 - packages/util/retention/README.i18n.yaml | 6 - packages/util/timeout/README.i18n.yaml | 4 +- packages/util/timeout/README.md | 2 +- packages/util/timeout/README.zh.md | 2 +- packages/util/timeout/tsconfig.json | 2 +- packages/web/README.i18n.yaml | 4 +- packages/web/README.md | 2 +- packages/web/README.zh.md | 2 +- packages/web/tool-web/README.i18n.yaml | 4 +- packages/web/tool-web/README.md | 8 +- packages/web/tool-web/README.zh.md | 8 +- packages/web/tool-web/package.json | 4 +- packages/web/tool-web/src/fetch.ts | 4 +- packages/web/tool-web/src/index.ts | 2 +- packages/web/tool-web/src/search.ts | 2 +- .../web/tool-web/tests/integration.spec.ts | 24 +- packages/web/tool-web/tests/load-path.spec.ts | 8 +- packages/web/tool-web/tests/spill.spec.ts | 10 +- packages/web/tool-web/tests/tool-web.spec.ts | 24 +- packages/web/tool-web/tsconfig.json | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 6 +- .../README.zh.md | 6 +- .../package.json | 4 +- .../src/index.ts | 24 +- .../src/invariant.ts | 8 +- .../src/policy.ts | 2 +- .../src/provider.ts | 10 +- .../tests/fetch-http.spec.ts} | 40 +- .../tsconfig.json | 2 +- packages/web/web-search-deepseek/package.json | 4 +- packages/web/web-search-deepseek/src/index.ts | 6 +- .../web-search-deepseek/tests/deepseek.e2e.ts | 2 +- .../tests/deepseek.spec.ts | 22 +- .../tests/settings.spec.ts | 8 +- .../web/web-search-deepseek/tsconfig.json | 4 +- packages/web/web-search-exa/package.json | 4 +- packages/web/web-search-exa/src/index.ts | 4 +- packages/web/web-search-exa/tests/exa.e2e.ts | 2 +- packages/web/web-search-exa/tests/exa.spec.ts | 10 +- packages/web/web-search-exa/tsconfig.json | 4 +- .../web/web-search-perplexity/package.json | 4 +- .../web/web-search-perplexity/src/index.ts | 4 +- .../tests/perplexity.e2e.ts | 2 +- .../tests/perplexity.spec.ts | 10 +- .../web/web-search-perplexity/tsconfig.json | 4 +- packages/web/web/README.i18n.yaml | 4 +- packages/web/web/README.md | 6 +- packages/web/web/README.zh.md | 6 +- packages/web/web/src/index.ts | 12 +- packages/web/web/tests/web.spec.ts | 20 +- packages/web/web/tsconfig.json | 2 +- packages/workflow/README.i18n.yaml | 4 +- packages/workflow/README.md | 4 +- packages/workflow/README.zh.md | 4 +- packages/workflow/tool-ralph/README.i18n.yaml | 4 +- packages/workflow/tool-ralph/README.md | 6 +- packages/workflow/tool-ralph/README.zh.md | 6 +- packages/workflow/tool-ralph/package.json | 6 +- packages/workflow/tool-ralph/src/index.ts | 4 +- .../tool-ralph/tests/integration.spec.ts | 16 +- .../tool-ralph/tests/tool-ralph.spec.ts | 16 +- packages/workflow/tool-ralph/tsconfig.json | 2 +- .../workflow/tool-workflow/README.i18n.yaml | 4 +- packages/workflow/tool-workflow/README.md | 2 +- packages/workflow/tool-workflow/README.zh.md | 2 +- packages/workflow/tool-workflow/package.json | 4 +- packages/workflow/tool-workflow/src/index.ts | 6 +- .../tool-workflow/tests/invariant.spec.ts | 8 +- .../tool-workflow/tests/tool-workflow.spec.ts | 26 +- packages/workflow/tool-workflow/tsconfig.json | 2 +- .../README.i18n.yaml | 6 +- .../README.md | 6 +- .../README.zh.md | 6 +- .../package.json | 6 +- .../src/host.ts | 14 +- .../src/index.ts | 12 +- .../src/invariant.ts | 8 +- .../src/meta.ts | 2 +- .../src/protocol.ts | 2 +- .../src/realm.ts | 2 +- .../src/runtime.ts | 2 +- .../src/session.ts | 2 +- .../src/types.ts | 2 +- .../src/worker.ts | 2 +- .../tests/built-worker.e2e.ts | 10 +- .../tests/integration.spec.ts | 22 +- .../tests/meta.spec.ts | 0 .../tests/realm.spec.ts | 0 .../tests/session.spec.ts | 0 .../tests/source-worker.compat.spec.ts | 10 +- .../tests/workflow-worker-thread.e2e.ts} | 20 +- .../tests/workflow-worker-thread.spec.ts} | 150 +- .../tsconfig.json | 2 +- .../tsdown.config.ts | 0 packages/workflow/workflow/README.i18n.yaml | 4 +- packages/workflow/workflow/README.md | 6 +- packages/workflow/workflow/README.zh.md | 6 +- packages/workflow/workflow/package.json | 2 +- packages/workflow/workflow/src/index.ts | 10 +- .../workflow/workflow/tests/invariant.spec.ts | 4 +- .../workflow/workflow/tests/workflow.spec.ts | 24 +- packages/workflow/workflow/tsconfig.json | 2 +- packages/workspace/README.i18n.yaml | 4 +- packages/workspace/README.md | 2 +- packages/workspace/README.zh.md | 2 +- packages/workspace/workspace/README.i18n.yaml | 4 +- packages/workspace/workspace/README.md | 14 +- packages/workspace/workspace/README.zh.md | 14 +- packages/workspace/workspace/package.json | 2 +- packages/workspace/workspace/src/index.ts | 6 +- packages/workspace/workspace/src/invariant.ts | 8 +- .../workspace/tests/invariant.spec.ts | 6 +- .../workspace/tests/workspace.spec.ts | 8 +- packages/workspace/workspace/tsconfig.json | 2 +- pnpm-lock.yaml | 1688 ++++++++--------- python/sdk-runtime/README.i18n.yaml | 4 +- python/sdk-runtime/README.md | 4 +- python/sdk-runtime/README.zh.md | 4 +- python/sdk-runtime/package.json | 64 +- .../src/deepseek_harness_runtime/__init__.py | 4 +- .../runtime/cordis.yml | 4 +- python/sdk/README.i18n.yaml | 4 +- python/sdk/README.md | 2 +- python/sdk/README.zh.md | 2 +- python/sdk/tests/test_bundled_runtime.py | 4 +- scripts/build-exe-for-python-sdk.ts | 2 +- scripts/check-workspace-constraints.ts | 10 +- scripts/ci-workflow.spec.ts | 6 +- scripts/doc-typecheck-paths.spec.ts | 6 +- scripts/gen-cordis-catalog.ts | 140 +- scripts/gen-doc-graphs.ts | 102 +- scripts/gen-third-party-notices.spec.ts | 4 +- scripts/gen-third-party-notices.ts | 4 +- scripts/gen-tool-catalog.ts | 134 +- scripts/oxlint-contract.spec.ts | 4 +- scripts/package-invariants.spec.ts | 4 +- scripts/package-invariants.ts | 4 +- scripts/publication-payload.spec.ts | 6 +- scripts/publication-payload.ts | 2 +- scripts/release/families.spec.ts | 2 +- scripts/rescope-vendor.ts | 4 +- scripts/run-gates.spec.ts | 2 +- scripts/run-gates.ts | 10 +- scripts/smoke-python-runtime.py | 12 +- .../advanced/result.json | 48 +- .../advanced/session.1.jsonl | 2 +- .../advanced/session.2.jsonl | 2 +- .../advanced/session.jsonl | 6 +- .../request-response.expected.json | 10 +- scripts/test-invariants.spec.ts | 8 +- scripts/test-invariants.ts | 6 +- scripts/type-equiv.manifest.json | 262 +-- scripts/verify-cordis-config.ts | 4 +- .../verify-package-readme-model-experience.ts | 76 +- tsconfig.base.json | 72 +- tsconfig.client.json | 32 +- tsconfig.host.json | 104 +- tsdown.config.ts | 2 +- vitest.config.ts | 56 +- website/docs.ts | 16 +- 3281 files changed, 21730 insertions(+), 21592 deletions(-) rename .agents/notes/implemented/architecture/{2026-07-26-task-registry-seam.i18n.yaml => 2026-07-26-job-registry-seam.i18n.yaml} (59%) create mode 100644 .agents/notes/implemented/architecture/2026-07-26-job-registry-seam.md create mode 100644 .agents/notes/implemented/architecture/2026-07-26-job-registry-seam.zh.md delete mode 100644 .agents/notes/implemented/architecture/2026-07-26-task-registry-seam.md delete mode 100644 .agents/notes/implemented/architecture/2026-07-26-task-registry-seam.zh.md rename .agents/notes/implemented/bug-fix/{2026-08-11-bounded-background-task-admission.i18n.yaml => 2026-08-11-bounded-background-job-admission.i18n.yaml} (55%) rename .agents/notes/implemented/bug-fix/{2026-08-11-bounded-background-task-admission.md => 2026-08-11-bounded-background-job-admission.md} (64%) rename .agents/notes/implemented/bug-fix/{2026-08-11-bounded-background-task-admission.zh.md => 2026-08-11-bounded-background-job-admission.zh.md} (69%) rename .agents/notes/implemented/feature/{2026-08-08-web-background-task-display.i18n.yaml => 2026-08-08-web-background-job-display.i18n.yaml} (57%) create mode 100644 .agents/notes/implemented/feature/2026-08-08-web-background-job-display.md create mode 100644 .agents/notes/implemented/feature/2026-08-08-web-background-job-display.zh.md delete mode 100644 .agents/notes/implemented/feature/2026-08-08-web-background-task-display.md delete mode 100644 .agents/notes/implemented/feature/2026-08-08-web-background-task-display.zh.md rename .agents/notes/implemented/feature/{2026-08-11-background-task-completion-wakes-an-idle-owner.i18n.yaml => 2026-08-11-background-job-completion-wakes-an-idle-owner.i18n.yaml} (51%) rename .agents/notes/implemented/feature/{2026-08-11-background-task-completion-wakes-an-idle-owner.md => 2026-08-11-background-job-completion-wakes-an-idle-owner.md} (65%) rename .agents/notes/implemented/feature/{2026-08-11-background-task-completion-wakes-an-idle-owner.zh.md => 2026-08-11-background-job-completion-wakes-an-idle-owner.zh.md} (73%) rename apps/web/tests/{background-task-list.e2e.ts => background-job-list.e2e.ts} (83%) rename apps/web/tests/snapshots/{background-task-list => background-job-list}/running.expected.md (64%) rename apps/web/tests/snapshots/{background-task-list => background-job-list}/settled.expected.md (68%) rename docs/subsystems/{pty.i18n.yaml => jobs.i18n.yaml} (73%) rename docs/subsystems/{tasks.md => jobs.md} (56%) rename docs/subsystems/{tasks.zh.md => jobs.zh.md} (56%) create mode 100644 docs/subsystems/permission-presets.i18n.yaml rename docs/subsystems/{permission.md => permission-presets.md} (75%) rename docs/subsystems/{permission.zh.md => permission-presets.zh.md} (75%) create mode 100644 docs/subsystems/session-telemetry.i18n.yaml rename docs/subsystems/{telemetry.md => session-telemetry.md} (70%) rename docs/subsystems/{telemetry.zh.md => session-telemetry.zh.md} (69%) rename docs/subsystems/{bash.i18n.yaml => shell.i18n.yaml} (72%) rename docs/subsystems/{bash.md => shell.md} (69%) rename docs/subsystems/{bash.zh.md => shell.zh.md} (71%) delete mode 100644 docs/subsystems/telemetry.i18n.yaml rename docs/subsystems/{tasks.i18n.yaml => terminal.i18n.yaml} (71%) rename docs/subsystems/{pty.md => terminal.md} (58%) rename docs/subsystems/{pty.zh.md => terminal.zh.md} (59%) delete mode 100644 docs/subsystems/user-interaction.i18n.yaml rename docs/subsystems/{http-server.i18n.yaml => user-questions.i18n.yaml} (68%) rename docs/subsystems/{user-interaction.md => user-questions.md} (82%) rename docs/subsystems/{user-interaction.zh.md => user-questions.zh.md} (82%) rename docs/subsystems/{permission.i18n.yaml => web-server.i18n.yaml} (70%) rename docs/subsystems/{http-server.md => web-server.md} (74%) rename docs/subsystems/{http-server.zh.md => web-server.zh.md} (73%) rename examples/acp-agent/{workspace-context.cordis.snapshot.yml => agent-instructions.cordis.snapshot.yml} (93%) rename examples/acp-agent/{workspace-context.cordis.yml => agent-instructions.cordis.yml} (100%) rename examples/acp-agent/{background-task-admission.cordis.snapshot.yml => background-job-admission.cordis.snapshot.yml} (91%) rename examples/acp-agent/{background-task-admission.cordis.yml => background-job-admission.cordis.yml} (96%) rename examples/acp-agent/tests/fixtures/{bash => shell}/tool-pwsh/cordis.yml (76%) rename examples/acp-agent/tests/fixtures/{bash => shell}/tool-pwsh/driver.ts (95%) rename examples/acp-agent/tests/goal-snapshots/{goal-session => goal-round-driver}/input.json (100%) rename examples/acp-agent/tests/goal-snapshots/{goal-session => goal-round-driver}/replay.override.json (91%) rename examples/acp-agent/tests/goal-snapshots/{goal-session => goal-round-driver}/session.expected.jsonl (69%) rename examples/acp-agent/tests/goal-snapshots/{goal-session => goal-round-driver}/session.jsonl (100%) rename examples/acp-agent/tests/goal-snapshots/{goal-session => goal-round-driver}/stdout.expected.jsonl (100%) rename examples/acp-agent/tests/snapshots/{workspace-context => agent-instructions}/input.json (100%) rename examples/acp-agent/tests/snapshots/{workspace-context => agent-instructions}/replay.override.json (100%) rename examples/acp-agent/tests/snapshots/{workspace-context => agent-instructions}/session.jsonl (82%) rename examples/acp-agent/tests/snapshots/{workspace-context => agent-instructions}/stdout.expected.jsonl (100%) rename examples/acp-agent/tests/snapshots/{workspace-context => agent-instructions}/system-prompt.expected.md (80%) rename examples/acp-agent/tests/snapshots/{workspace-context => agent-instructions}/workspace/.dsh-project (100%) rename examples/acp-agent/tests/snapshots/{workspace-context => agent-instructions}/workspace/AGENTS.canonical.md (100%) rename examples/acp-agent/tests/snapshots/{workspace-context => agent-instructions}/workspace/AGENTS.md (100%) rename examples/acp-agent/tests/snapshots/{workspace-context => agent-instructions}/workspace/nested/AGENTS.canonical.md (100%) rename examples/acp-agent/tests/snapshots/{workspace-context => agent-instructions}/workspace/nested/AGENTS.md (100%) rename examples/acp-agent/tests/snapshots/{workspace-context => agent-instructions}/workspace/nested/task.txt (100%) rename examples/acp-agent/tests/snapshots/{background-task-admission => background-job-admission}/input.json (58%) rename examples/acp-agent/tests/snapshots/{background-task-admission => background-job-admission}/replay.override.json (84%) rename examples/acp-agent/tests/snapshots/{background-task-admission => background-job-admission}/session.jsonl (78%) rename examples/acp-agent/tests/snapshots/{background-task-admission => background-job-admission}/stdout.expected.jsonl (100%) rename examples/acp-agent/tests/snapshots/{repeat-tool-guard => repeat-tool-reminder}/input.json (100%) rename examples/acp-agent/tests/snapshots/{repeat-tool-guard => repeat-tool-reminder}/session.jsonl (96%) rename examples/acp-agent/tests/snapshots/{repeat-tool-guard => repeat-tool-reminder}/stdout.expected.jsonl (100%) rename examples/acp-agent/tests/snapshots/{subagent-fork => subagent-fork-in-process}/input.json (100%) rename examples/acp-agent/tests/snapshots/{subagent-fork => subagent-fork-in-process}/session.1.jsonl (100%) rename examples/acp-agent/tests/snapshots/{subagent-fork => subagent-fork-in-process}/session.jsonl (100%) rename examples/acp-agent/tests/snapshots/{subagent-fork => subagent-fork-in-process}/stdout.expected.jsonl (100%) rename examples/acp-agent/tests/snapshots/{subagent-spawn => subagent-spawn-in-process}/input.json (100%) rename examples/acp-agent/tests/snapshots/{subagent-spawn => subagent-spawn-in-process}/session.1.jsonl (100%) rename examples/acp-agent/tests/snapshots/{subagent-spawn => subagent-spawn-in-process}/session.jsonl (100%) rename examples/acp-agent/tests/snapshots/{subagent-spawn => subagent-spawn-in-process}/stdout.expected.jsonl (100%) rename examples/headless-agent/tests/fixtures/{telemetry-otel-driver.ts => session-telemetry-otel-driver.ts} (91%) rename examples/headless-agent/tests/fixtures/{telemetry-otel.cordis.yml => session-telemetry-otel.cordis.yml} (92%) rename examples/jsonrpc-agent/tests/snapshots/{subagent-spawn => subagent-spawn-in-process}/notifications.expected.jsonl (100%) rename examples/jsonrpc-agent/tests/snapshots/{subagent-spawn => subagent-spawn-in-process}/result.expected.json (100%) rename examples/jsonrpc-agent/tests/snapshots/{subagent-spawn => subagent-spawn-in-process}/session.1.jsonl (100%) rename examples/jsonrpc-agent/tests/snapshots/{subagent-spawn => subagent-spawn-in-process}/session.jsonl (100%) delete mode 100644 packages/bash/bash-env/README.md delete mode 100644 packages/bash/bash-env/README.zh.md delete mode 100644 packages/bash/bash/README.zh.md delete mode 100644 packages/bash/pwsh-local/README.i18n.yaml delete mode 100644 packages/bash/pwsh-sandbox/README.i18n.yaml delete mode 100644 packages/bash/tool-bash/README.i18n.yaml delete mode 100644 packages/bash/tool-pwsh/README.i18n.yaml delete mode 100644 packages/client/ui-command/tsdown.config.ts rename packages/client/{ui-models => ui-commands}/README.i18n.yaml (70%) rename packages/client/{ui-command => ui-commands}/README.md (73%) rename packages/client/{ui-command => ui-commands}/README.zh.md (73%) rename packages/client/{ui-command => ui-commands}/package.json (90%) rename packages/client/{ui-command => ui-commands}/src/client/PopupSelectView.module.css (100%) rename packages/client/{ui-command => ui-commands}/src/client/PopupSelectView.tsx (100%) rename packages/client/{ui-command => ui-commands}/src/client/contract.ts (92%) rename packages/client/{ui-command => ui-commands}/src/client/directory.ts (100%) rename packages/client/{ui-command => ui-commands}/src/client/index.ts (78%) rename packages/client/{ui-command => ui-commands}/src/client/locales.ts (100%) rename packages/client/{ui-command => ui-commands}/src/client/popup.ts (97%) rename packages/client/{ui-command => ui-commands}/src/client/service.ts (93%) rename packages/client/{ui-command => ui-commands}/src/css-modules.d.ts (100%) rename packages/client/{ui-command => ui-commands}/src/index.ts (92%) rename packages/client/{ui-command => ui-commands}/src/invariant.ts (84%) rename packages/client/{ui-command => ui-commands}/tests/browser-plugin.client.spec.ts (71%) rename packages/client/{ui-command => ui-commands}/tests/directory.client.spec.ts (100%) rename packages/client/{ui-command => ui-commands}/tests/popup-view.client.spec.tsx (100%) rename packages/client/{ui-command => ui-commands}/tests/popup.client.spec.ts (100%) rename packages/client/{ui-command => ui-commands}/tests/service.client.spec.ts (97%) rename packages/client/{ui-command => ui-commands}/tsconfig.json (88%) rename packages/client/{ui-question => ui-commands}/tsdown.config.ts (62%) create mode 100644 packages/client/ui-directory-picker-browse/README.i18n.yaml rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/README.md (98%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/README.zh.md (98%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/package.json (94%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/src/client/DirectoryBrowser.module.css (100%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/src/client/DirectoryBrowser.tsx (100%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/src/client/flow.ts (100%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/src/client/index.ts (100%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/src/css-modules.d.ts (100%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/src/index.ts (100%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/src/invariant.ts (85%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/tests/client-flow.client.spec.tsx (96%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/tests/directory-browser.client.spec.tsx (100%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/tsconfig.json (88%) rename packages/client/{ui-directory-picker => ui-directory-picker-browse}/tsdown.config.ts (63%) delete mode 100644 packages/client/ui-feedback/tsdown.config.ts rename packages/client/{test-runtime => ui-input-trigger}/README.i18n.yaml (69%) create mode 100644 packages/client/ui-input-trigger/README.md create mode 100644 packages/client/ui-input-trigger/README.zh.md rename packages/client/{ui-slash => ui-input-trigger}/package.json (95%) rename packages/client/{ui-slash => ui-input-trigger}/src/client/MenuView.module.css (100%) rename packages/client/{ui-slash => ui-input-trigger}/src/client/MenuView.tsx (98%) rename packages/client/{ui-slash => ui-input-trigger}/src/client/contract.ts (52%) rename packages/client/{ui-slash => ui-input-trigger}/src/client/controller.ts (92%) rename packages/client/{ui-slash => ui-input-trigger}/src/client/index.ts (71%) rename packages/client/{ui-slash => ui-input-trigger}/src/client/locales.ts (100%) rename packages/client/{ui-slash => ui-input-trigger}/src/client/service.ts (76%) rename packages/client/{ui-slash => ui-input-trigger}/src/client/slots.ts (91%) rename packages/client/{ui-slash => ui-input-trigger}/src/core/contract.ts (88%) rename packages/client/{ui-slash => ui-input-trigger}/src/core/detect.ts (100%) rename packages/client/{ui-slash => ui-input-trigger}/src/core/menu.ts (97%) rename packages/client/{ui-feedback => ui-input-trigger}/src/css-modules.d.ts (100%) rename packages/client/{ui-slash => ui-input-trigger}/src/index.ts (100%) rename packages/client/{ui-slash => ui-input-trigger}/src/invariant.ts (83%) rename packages/client/{ui-slash => ui-input-trigger}/src/types.ts (96%) rename packages/client/{ui-slash => ui-input-trigger}/tests/apply.client.spec.ts (79%) rename packages/client/{ui-slash => ui-input-trigger}/tests/core-detect.client.spec.ts (100%) rename packages/client/{ui-slash => ui-input-trigger}/tests/core-menu.client.spec.ts (100%) rename packages/client/{ui-slash => ui-input-trigger}/tests/menu-view.client.spec.tsx (98%) rename packages/client/{ui-slash => ui-input-trigger}/tests/service.client.spec.ts (88%) rename packages/client/{ui-slash => ui-input-trigger}/tsconfig.json (88%) create mode 100644 packages/client/ui-input-trigger/tsdown.config.ts rename packages/client/{ui-task => ui-jobs}/README.i18n.yaml (71%) create mode 100644 packages/client/ui-jobs/README.md rename packages/client/{ui-task => ui-jobs}/README.zh.md (82%) rename packages/client/{ui-task => ui-jobs}/package.json (91%) rename packages/client/{ui-task/src/client/TaskListAction.module.css => ui-jobs/src/client/JobListAction.module.css} (96%) rename packages/client/{ui-task/src/client/TaskListAction.tsx => ui-jobs/src/client/JobListAction.tsx} (69%) rename packages/client/{ui-task => ui-jobs}/src/client/index.ts (59%) rename packages/client/{ui-task => ui-jobs}/src/client/locales.ts (73%) rename packages/client/{ui-model => ui-jobs}/src/css-modules.d.ts (100%) rename packages/client/{ui-task => ui-jobs}/src/index.ts (79%) rename packages/client/{ui-task => ui-jobs}/src/invariant.ts (80%) rename packages/client/{ui-task => ui-jobs}/tests/browser-plugin.client.spec.ts (79%) rename packages/client/{ui-task/tests/task-list-action.client.spec.tsx => ui-jobs/tests/job-list-action.client.spec.tsx} (55%) rename packages/client/{ui-task => ui-jobs}/tsconfig.json (89%) rename packages/client/{ui-task => ui-jobs}/tsdown.config.ts (61%) rename packages/client/{ui-directory-picker => ui-message-feedback}/README.i18n.yaml (69%) rename packages/client/{ui-feedback => ui-message-feedback}/README.md (83%) rename packages/client/{ui-feedback => ui-message-feedback}/README.zh.md (80%) rename packages/client/{ui-feedback => ui-message-feedback}/package.json (92%) rename packages/client/{ui-feedback/src/client/FeedbackActions.module.css => ui-message-feedback/src/client/MessageFeedbackActions.module.css} (100%) rename packages/client/{ui-feedback/src/client/FeedbackActions.tsx => ui-message-feedback/src/client/MessageFeedbackActions.tsx} (94%) rename packages/client/{ui-feedback => ui-message-feedback}/src/client/controller.ts (88%) rename packages/client/{ui-feedback => ui-message-feedback}/src/client/index.ts (72%) rename packages/client/{ui-feedback => ui-message-feedback}/src/client/locales.ts (91%) rename packages/client/{ui-feedback => ui-message-feedback}/src/client/slots.ts (77%) rename packages/client/{ui-models => ui-message-feedback}/src/css-modules.d.ts (100%) rename packages/client/{ui-feedback => ui-message-feedback}/src/index.ts (100%) rename packages/client/{ui-feedback => ui-message-feedback}/src/invariant.ts (88%) rename packages/client/{ui-feedback => ui-message-feedback}/tests/browser-plugin.client.spec.tsx (94%) rename packages/client/{ui-feedback => ui-message-feedback}/tests/controller.client.spec.ts (89%) rename packages/client/{ui-feedback/tests/feedback-actions.client.spec.tsx => ui-message-feedback/tests/message-feedback-actions.client.spec.tsx} (86%) rename packages/client/{ui-feedback => ui-message-feedback}/tsconfig.json (86%) create mode 100644 packages/client/ui-message-feedback/tsdown.config.ts rename packages/client/{ui-model => ui-model-selection}/README.i18n.yaml (69%) rename packages/client/{ui-model => ui-model-selection}/README.md (72%) rename packages/client/{ui-model => ui-model-selection}/README.zh.md (72%) rename packages/client/{ui-model => ui-model-selection}/package.json (85%) rename packages/client/{ui-model => ui-model-selection}/src/client/ModelSelect.module.css (100%) rename packages/client/{ui-model => ui-model-selection}/src/client/ModelSelect.tsx (100%) rename packages/client/{ui-model => ui-model-selection}/src/client/directory.ts (100%) rename packages/client/{ui-model => ui-model-selection}/src/client/index.ts (88%) rename packages/client/{ui-model => ui-model-selection}/src/client/locales.ts (100%) rename packages/client/{ui-model => ui-model-selection}/src/client/service.ts (83%) rename packages/client/{ui-model => ui-model-selection}/src/client/slots.ts (100%) rename packages/client/{ui-plugins => ui-model-selection}/src/css-modules.d.ts (100%) rename packages/client/{ui-model => ui-model-selection}/src/index.ts (100%) rename packages/client/{ui-model => ui-model-selection}/src/invariant.ts (81%) rename packages/client/{ui-model => ui-model-selection}/tests/browser-plugin.client.spec.ts (95%) rename packages/client/{ui-model => ui-model-selection}/tests/model-select.client.spec.tsx (100%) rename packages/client/{ui-model => ui-model-selection}/tsconfig.json (83%) create mode 100644 packages/client/ui-model-selection/tsdown.config.ts delete mode 100644 packages/client/ui-model/tsdown.config.ts delete mode 100644 packages/client/ui-models/tsdown.config.ts create mode 100644 packages/client/ui-permission-presets/README.i18n.yaml rename packages/client/{ui-permission => ui-permission-presets}/README.md (59%) rename packages/client/{ui-permission => ui-permission-presets}/README.zh.md (61%) rename packages/client/{ui-permission => ui-permission-presets}/package.json (83%) rename packages/client/{ui-permission => ui-permission-presets}/src/client/PermissionRow.module.css (100%) rename packages/client/{ui-permission => ui-permission-presets}/src/client/PermissionRow.tsx (100%) rename packages/client/{ui-permission => ui-permission-presets}/src/client/index.ts (93%) rename packages/client/{ui-permission => ui-permission-presets}/src/client/locales.ts (100%) rename packages/client/{ui-permission => ui-permission-presets}/src/client/presentation.ts (100%) rename packages/client/{ui-permission => ui-permission-presets}/src/client/settings-store.ts (98%) rename packages/client/{ui-permission => ui-permission-presets}/src/css-modules.d.ts (100%) rename packages/client/{ui-permission => ui-permission-presets}/src/index.ts (100%) rename packages/client/{ui-permission => ui-permission-presets}/src/invariant.ts (81%) rename packages/client/{ui-permission => ui-permission-presets}/tests/browser-plugin.client.spec.ts (96%) rename packages/client/{ui-permission/tests/permission-row.client.spec.tsx => ui-permission-presets/tests/permission-presets-row.client.spec.tsx} (92%) rename packages/client/{ui-permission => ui-permission-presets}/tests/settings-store.client.spec.ts (92%) rename packages/client/{ui-permission => ui-permission-presets}/tsconfig.json (78%) rename packages/client/{ui-permission => ui-permission-presets}/tsdown.config.ts (64%) delete mode 100644 packages/client/ui-permission/README.i18n.yaml delete mode 100644 packages/client/ui-plugin-config/README.i18n.yaml delete mode 100644 packages/client/ui-plugin-config/tsdown.config.ts delete mode 100644 packages/client/ui-plugins/README.i18n.yaml delete mode 100644 packages/client/ui-plugins/tsdown.config.ts delete mode 100644 packages/client/ui-question/README.i18n.yaml rename packages/client/{ui-feedback => ui-settings-models}/README.i18n.yaml (69%) rename packages/client/{ui-models => ui-settings-models}/README.md (99%) rename packages/client/{ui-models => ui-settings-models}/README.zh.md (99%) rename packages/client/{ui-models => ui-settings-models}/package.json (95%) rename packages/client/{ui-models => ui-settings-models}/src/client/CustomProviderCard.tsx (100%) rename packages/client/{ui-models => ui-settings-models}/src/client/DeepSeekModelsEditor.tsx (100%) rename packages/client/{ui-models => ui-settings-models}/src/client/DeepSeekOnboardingDialog.module.css (100%) rename packages/client/{ui-models => ui-settings-models}/src/client/DeepSeekOnboardingDialog.tsx (100%) rename packages/client/{ui-models => ui-settings-models}/src/client/EditorFooter.tsx (97%) rename packages/client/{ui-models => ui-settings-models}/src/client/ModelListEditor.tsx (100%) rename packages/client/{ui-models => ui-settings-models}/src/client/ModelsSection.module.css (100%) rename packages/client/{ui-models => ui-settings-models}/src/client/ModelsSection.tsx (100%) rename packages/client/{ui-models => ui-settings-models}/src/client/ProviderEditor.tsx (100%) rename packages/client/{ui-models => ui-settings-models}/src/client/apiKey.ts (97%) rename packages/client/{ui-models => ui-settings-models}/src/client/index.ts (96%) rename packages/client/{ui-models => ui-settings-models}/src/client/locales.ts (100%) rename packages/client/{ui-models => ui-settings-models}/src/client/store.ts (100%) rename packages/client/{ui-slash => ui-settings-models}/src/css-modules.d.ts (100%) rename packages/client/{ui-models => ui-settings-models}/src/index.ts (100%) rename packages/client/{ui-models => ui-settings-models}/src/invariant.ts (81%) rename packages/client/{ui-models => ui-settings-models}/tests/apply.client.spec.ts (95%) rename packages/client/{ui-models => ui-settings-models}/tests/components.client.spec.tsx (100%) rename packages/client/{ui-models => ui-settings-models}/tests/invariant.client.spec.ts (70%) rename packages/client/{ui-models => ui-settings-models}/tests/onboarding-dialog.client.spec.tsx (100%) rename packages/client/{ui-models => ui-settings-models}/tests/provider-form.client.spec.tsx (100%) rename packages/client/{ui-models => ui-settings-models}/tests/readiness.client.spec.ts (100%) rename packages/client/{ui-models => ui-settings-models}/tests/store.client.spec.ts (100%) rename packages/client/{ui-models => ui-settings-models}/tests/styles.client.spec.ts (100%) rename packages/client/{ui-models => ui-settings-models}/tsconfig.json (92%) create mode 100644 packages/client/ui-settings-models/tsdown.config.ts create mode 100644 packages/client/ui-settings-plugin-inventory/README.i18n.yaml rename packages/client/{ui-plugins => ui-settings-plugin-inventory}/README.md (97%) rename packages/client/{ui-plugins => ui-settings-plugin-inventory}/README.zh.md (97%) rename packages/client/{ui-plugins => ui-settings-plugin-inventory}/package.json (94%) rename packages/client/{ui-plugins/src/client/PluginSettingsSection.module.css => ui-settings-plugin-inventory/src/client/PluginInventorySettingsTab.module.css} (100%) rename packages/client/{ui-plugins/src/client/PluginSettingsSection.tsx => ui-settings-plugin-inventory/src/client/PluginInventorySettingsTab.tsx} (93%) rename packages/client/{ui-plugins => ui-settings-plugin-inventory}/src/client/index.ts (61%) rename packages/client/{ui-plugins => ui-settings-plugin-inventory}/src/client/locales.ts (92%) rename packages/client/{ui-task => ui-settings-plugin-inventory}/src/css-modules.d.ts (100%) rename packages/client/{ui-plugins => ui-settings-plugin-inventory}/src/index.ts (100%) rename packages/client/{ui-plugins => ui-settings-plugin-inventory}/src/invariant.ts (78%) rename packages/client/{ui-plugins => ui-settings-plugin-inventory}/tests/browser-plugin.client.spec.tsx (80%) rename packages/client/{ui-plugins => ui-settings-plugin-inventory}/tests/components.client.spec.tsx (79%) rename packages/client/{ui-plugins => ui-settings-plugin-inventory}/tests/invariant.client.spec.ts (70%) rename packages/client/{ui-plugins => ui-settings-plugin-inventory}/tsconfig.json (90%) create mode 100644 packages/client/ui-settings-plugin-inventory/tsdown.config.ts create mode 100644 packages/client/ui-settings-plugins/README.i18n.yaml rename packages/client/{ui-plugin-config => ui-settings-plugins}/README.md (99%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/README.zh.md (99%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/package.json (95%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/client/AgentLoopCard.tsx (93%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/client/BashCard.tsx (95%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/client/ConfigurablePluginsTab.tsx (91%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/client/PluginCard.module.css (100%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/client/PluginCard.tsx (93%) rename packages/client/{ui-plugin-config/src/client/PluginConfigSection.module.css => ui-settings-plugins/src/client/PluginsSettingsSection.module.css} (100%) rename packages/client/{ui-plugin-config/src/client/PluginConfigSection.tsx => ui-settings-plugins/src/client/PluginsSettingsSection.tsx} (86%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/client/WebSearchCard.tsx (96%) rename packages/client/{ui-plugin-config/src/client/agent-loop-store.ts => ui-settings-plugins/src/client/agent-loop-card-controller.ts} (97%) rename packages/client/{ui-plugin-config/src/client/bash-store.ts => ui-settings-plugins/src/client/bash-card-controller.ts} (96%) rename packages/client/{ui-plugin-config/src/client/card-store.ts => ui-settings-plugins/src/client/card-form.ts} (100%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/client/fields.module.css (100%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/client/fields.tsx (100%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/client/index.ts (86%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/client/locales.ts (96%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/client/slot-contract.ts (100%) rename packages/client/{ui-plugin-config/src/client/web-search-store.ts => ui-settings-plugins/src/client/web-search-card-controller.ts} (99%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/css-modules.d.ts (100%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/index.ts (100%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/src/invariant.ts (82%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/tests/apply.client.spec.ts (89%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/tests/fields.client.spec.tsx (100%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/tests/invariant.client.spec.ts (76%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/tests/section.client.spec.tsx (95%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/tests/stores.client.spec.ts (99%) rename packages/client/{ui-plugin-config => ui-settings-plugins}/tsconfig.json (84%) create mode 100644 packages/client/ui-settings-plugins/tsdown.config.ts delete mode 100644 packages/client/ui-slash/README.i18n.yaml delete mode 100644 packages/client/ui-slash/README.md delete mode 100644 packages/client/ui-slash/README.zh.md delete mode 100644 packages/client/ui-slash/tsdown.config.ts delete mode 100644 packages/client/ui-task/README.md rename packages/client/{ui-command => ui-user-questions}/README.i18n.yaml (69%) rename packages/client/{ui-question => ui-user-questions}/README.md (98%) rename packages/client/{ui-question => ui-user-questions}/README.zh.md (98%) rename packages/client/{ui-question => ui-user-questions}/package.json (92%) rename packages/client/{ui-question => ui-user-questions}/src/client/PlanReviewPanel.module.css (100%) rename packages/client/{ui-question => ui-user-questions}/src/client/PlanReviewPanel.tsx (100%) rename packages/client/{ui-question => ui-user-questions}/src/client/QuestionComposer.module.css (100%) rename packages/client/{ui-question => ui-user-questions}/src/client/QuestionComposer.tsx (100%) rename packages/client/{ui-question => ui-user-questions}/src/client/contract/slots.ts (100%) rename packages/client/{ui-question => ui-user-questions}/src/client/index.ts (96%) rename packages/client/{ui-question => ui-user-questions}/src/client/locales.ts (100%) rename packages/client/{ui-question => ui-user-questions}/src/css-modules.d.ts (100%) rename packages/client/{ui-question => ui-user-questions}/src/index.ts (100%) rename packages/client/{ui-question => ui-user-questions}/src/invariant.ts (82%) rename packages/client/{ui-question => ui-user-questions}/tests/browser-plugin.client.spec.ts (87%) rename packages/client/{ui-question => ui-user-questions}/tests/node-plugin.client.spec.ts (78%) rename packages/client/{ui-question => ui-user-questions}/tests/plan-review-panel.client.spec.tsx (100%) rename packages/client/{ui-question/tests/question-composer.client.spec.tsx => ui-user-questions/tests/user-questions-composer.client.spec.tsx} (100%) rename packages/client/{ui-question => ui-user-questions}/tsconfig.json (90%) create mode 100644 packages/client/ui-user-questions/tsdown.config.ts rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/README.i18n.yaml (67%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/README.md (90%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/README.zh.md (90%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/package.json (92%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/src/bootstrap.ts (99%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/src/index.ts (93%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/src/invariant.ts (81%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/src/output-json.ts (99%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/src/protocol.ts (97%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/src/worker-json.ts (99%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/src/worker.ts (74%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/tests/bootstrap.spec.ts (100%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/tests/built-lib.e2e.ts (94%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/tests/output-json.spec.ts (100%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/tests/runtime.spec.ts (96%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/tests/source-worker.compat.spec.ts (100%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/tests/worker-json.spec.ts (100%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/tsconfig.json (90%) rename packages/code-runtime/{code-runtime-worker => code-runtime-worker-thread}/tsdown.config.ts (100%) delete mode 100644 packages/compact/README.md rename packages/{compact => compaction}/README.i18n.yaml (71%) create mode 100644 packages/compaction/README.md rename packages/{compact => compaction}/README.zh.md (50%) rename packages/{compact => compaction}/command-compact/README.i18n.yaml (69%) rename packages/{compact => compaction}/command-compact/README.md (78%) rename packages/{compact => compaction}/command-compact/README.zh.md (77%) rename packages/{compact => compaction}/command-compact/package.json (89%) rename packages/{compact => compaction}/command-compact/src/index.ts (94%) rename packages/{compact => compaction}/command-compact/src/invariant.ts (100%) rename packages/{compact => compaction}/command-compact/tests/command-compact.spec.ts (92%) rename packages/{compact => compaction}/command-compact/tests/invariant.spec.ts (100%) rename packages/{compact => compaction}/command-compact/tests/loader-composition.spec.ts (88%) rename packages/{compact => compaction}/command-compact/tsconfig.json (81%) rename packages/{compact/compact => compaction/compaction-basic}/README.i18n.yaml (69%) rename packages/{compact/compact-basic => compaction/compaction-basic}/README.md (73%) rename packages/{compact/compact-basic => compaction/compaction-basic}/README.zh.md (73%) rename packages/{compact/compact-basic => compaction/compaction-basic}/package.json (83%) rename packages/{compact/compact-basic => compaction/compaction-basic}/src/config.ts (91%) rename packages/{compact/compact-basic => compaction/compaction-basic}/src/index.ts (94%) rename packages/{compact/compact-basic => compaction/compaction-basic}/src/invariant.ts (83%) rename packages/{compact/compact-basic => compaction/compaction-basic}/src/region.ts (94%) rename packages/{compact/compact-basic => compaction/compaction-basic}/src/summarizer.ts (97%) rename packages/{compact/compact-basic => compaction/compaction-basic}/src/types.ts (92%) rename packages/{compact/compact-basic/tests/compact-basic.spec.ts => compaction/compaction-basic/tests/compaction-basic.spec.ts} (92%) rename packages/{compact/compact-basic/tests/compact-loop-repro.spec.ts => compaction/compaction-basic/tests/compaction-loop-repro.spec.ts} (94%) rename packages/{compact/compact-basic => compaction/compaction-basic}/tests/loader-composition.spec.ts (69%) rename packages/{compact/compact-basic/tests/manual-compact.spec.ts => compaction/compaction-basic/tests/manual-compaction.spec.ts} (89%) rename packages/{compact/compact-basic => compaction/compaction-basic}/tsconfig.json (82%) rename packages/{compact/compact-tool-result-prune => compaction/compaction-tool-result-pruner}/README.i18n.yaml (67%) rename packages/{compact/compact-tool-result-prune => compaction/compaction-tool-result-pruner}/README.md (80%) rename packages/{compact/compact-tool-result-prune => compaction/compaction-tool-result-pruner}/README.zh.md (80%) rename packages/{compact/compact-tool-result-prune => compaction/compaction-tool-result-pruner}/package.json (86%) rename packages/{compact/compact-tool-result-prune => compaction/compaction-tool-result-pruner}/src/config.ts (100%) rename packages/{compact/compact-tool-result-prune => compaction/compaction-tool-result-pruner}/src/index.ts (93%) rename packages/{compact/compact-tool-result-prune => compaction/compaction-tool-result-pruner}/src/invariant.ts (79%) rename packages/{compact/compact-tool-result-prune => compaction/compaction-tool-result-pruner}/src/types.ts (100%) rename packages/{compact/compact-tool-result-prune => compaction/compaction-tool-result-pruner}/tests/loader-composition.spec.ts (76%) rename packages/{compact/compact-tool-result-prune/tests/tool-result-prune.spec.ts => compaction/compaction-tool-result-pruner/tests/tool-result-pruner.spec.ts} (93%) rename packages/{compact/compact-tool-result-prune => compaction/compaction-tool-result-pruner}/tsconfig.json (82%) rename packages/{compact/compact-basic => compaction/compaction}/README.i18n.yaml (70%) rename packages/{compact/compact => compaction/compaction}/README.md (60%) rename packages/{compact/compact => compaction/compaction}/README.zh.md (60%) rename packages/{compact/compact => compaction/compaction}/package.json (89%) rename packages/{compact/compact => compaction/compaction}/src/brand.ts (100%) rename packages/{compact/compact => compaction/compaction}/src/checkpoint.ts (88%) rename packages/{compact/compact => compaction/compaction}/src/index.ts (88%) rename packages/{compact/compact => compaction/compaction}/src/invariant.ts (79%) rename packages/{compact/compact => compaction/compaction}/src/tool-pairing.ts (99%) rename packages/{compact/compact => compaction/compaction}/src/types.ts (85%) rename packages/{compact/compact/tests/compact.spec.ts => compaction/compaction/tests/compaction.spec.ts} (76%) rename packages/{compact/compact => compaction/compaction}/tests/invariant.spec.ts (62%) rename packages/{compact/compact => compaction/compaction}/tests/tool-pairing.spec.ts (99%) rename packages/{compact/compact => compaction/compaction}/tsconfig.json (90%) rename packages/{compact/compact => compaction/compaction}/tsdown.config.ts (100%) rename packages/context/{workspace-context => agent-instructions}/README.i18n.yaml (69%) rename packages/context/{workspace-context => agent-instructions}/README.md (92%) rename packages/context/{workspace-context => agent-instructions}/README.zh.md (92%) rename packages/context/{workspace-context => agent-instructions}/package.json (89%) rename packages/context/{workspace-context => agent-instructions}/src/config.ts (97%) rename packages/context/{workspace-context => agent-instructions}/src/digest.ts (94%) rename packages/context/{workspace-context => agent-instructions}/src/files.ts (99%) rename packages/context/{workspace-context => agent-instructions}/src/index.ts (94%) rename packages/context/{workspace-context => agent-instructions}/src/invariant.ts (82%) rename packages/context/{workspace-context => agent-instructions}/src/render.ts (98%) rename packages/context/{workspace-context => agent-instructions}/src/state.ts (92%) rename packages/context/{workspace-context/tests/workspace-context.e2e.ts => agent-instructions/tests/agent-instructions.e2e.ts} (95%) rename packages/context/{workspace-context/tests/workspace-context.spec.ts => agent-instructions/tests/agent-instructions.spec.ts} (97%) rename packages/context/{workspace-context => agent-instructions}/tsconfig.json (85%) rename packages/core/{agent-tool-mode => agent-tool-presentation}/README.i18n.yaml (68%) rename packages/core/{agent-tool-mode => agent-tool-presentation}/README.md (85%) rename packages/core/{agent-tool-mode => agent-tool-presentation}/README.zh.md (86%) rename packages/core/{agent-tool-mode => agent-tool-presentation}/package.json (92%) rename packages/core/{agent-tool-mode => agent-tool-presentation}/src/index.ts (94%) rename packages/core/{agent-tool-mode => agent-tool-presentation}/src/invariant.ts (84%) rename packages/core/{agent-tool-mode/tests/agent-tool-mode.spec.ts => agent-tool-presentation/tests/agent-tool-presentation.spec.ts} (96%) rename packages/core/{agent-tool-mode => agent-tool-presentation}/tsconfig.json (88%) rename packages/{self-modification => extensions}/README.i18n.yaml (80%) rename packages/{self-modification => extensions}/README.md (100%) rename packages/{self-modification => extensions}/README.zh.md (100%) create mode 100644 packages/extensions/tool-cordis/README.i18n.yaml rename packages/{self-modification => extensions}/tool-cordis/README.md (89%) rename packages/{self-modification => extensions}/tool-cordis/README.zh.md (90%) rename packages/{self-modification => extensions}/tool-cordis/package.json (96%) rename packages/{self-modification => extensions}/tool-cordis/src/api-catalog.ts (93%) rename packages/{self-modification => extensions}/tool-cordis/src/fiber-state.ts (100%) rename packages/{self-modification => extensions}/tool-cordis/src/guard.ts (99%) rename packages/{self-modification => extensions}/tool-cordis/src/index.ts (97%) rename packages/{self-modification => extensions}/tool-cordis/src/inspect.ts (100%) rename packages/{self-modification => extensions}/tool-cordis/src/invariant.ts (100%) rename packages/{self-modification => extensions}/tool-cordis/src/mount.ts (100%) rename packages/{self-modification => extensions}/tool-cordis/src/present.ts (100%) rename packages/{self-modification => extensions}/tool-cordis/src/sandbox.ts (98%) rename packages/{self-modification => extensions}/tool-cordis/tests/cordis-lifecycle.spec.ts (100%) rename packages/{self-modification => extensions}/tool-cordis/tests/cross-mount.spec.ts (100%) rename packages/{self-modification => extensions}/tool-cordis/tests/helpers.ts (93%) rename packages/{self-modification => extensions}/tool-cordis/tests/inspect.spec.ts (96%) rename packages/{self-modification => extensions}/tool-cordis/tests/integration.spec.ts (100%) rename packages/{self-modification => extensions}/tool-cordis/tests/mount.spec.ts (100%) rename packages/{self-modification => extensions}/tool-cordis/tests/present.spec.ts (100%) rename packages/{self-modification => extensions}/tool-cordis/tests/sandbox-context.spec.ts (99%) rename packages/{self-modification => extensions}/tool-cordis/tests/tool-cordis.spec.ts (100%) rename packages/{self-modification => extensions}/tool-cordis/tests/unmount-hmr.spec.ts (97%) rename packages/{self-modification => extensions}/tool-cordis/tsconfig.json (90%) create mode 100644 packages/fs/fs-observation-policy/README.i18n.yaml rename packages/fs/{fs-policy => fs-observation-policy}/README.md (87%) rename packages/fs/{fs-policy => fs-observation-policy}/README.zh.md (87%) rename packages/fs/{fs-policy => fs-observation-policy}/package.json (92%) rename packages/fs/{fs-policy => fs-observation-policy}/src/index.ts (92%) rename packages/fs/{fs-policy => fs-observation-policy}/src/invariant.ts (76%) rename packages/fs/{fs-policy => fs-observation-policy}/src/types.ts (79%) rename packages/fs/{fs-policy => fs-observation-policy}/tests/policy.spec.ts (94%) rename packages/fs/{fs-policy => fs-observation-policy}/tsconfig.json (87%) rename packages/goal/{goal-session => goal-round-driver}/README.i18n.yaml (69%) rename packages/goal/{goal-session => goal-round-driver}/README.md (98%) rename packages/goal/{goal-session => goal-round-driver}/README.zh.md (98%) rename packages/goal/{goal-session => goal-round-driver}/package.json (93%) rename packages/goal/{goal-session => goal-round-driver}/src/index.ts (93%) rename packages/goal/{goal-session => goal-round-driver}/src/invariant.ts (94%) rename packages/goal/{goal-session => goal-round-driver}/src/prompt.ts (100%) rename packages/goal/{goal-session/tests/goal-session.spec.ts => goal-round-driver/tests/goal-round-driver.spec.ts} (99%) rename packages/goal/{goal-session => goal-round-driver}/tests/invariant.spec.ts (83%) rename packages/goal/{goal-session => goal-round-driver}/tsconfig.json (89%) rename packages/goal/{goal-session => goal-round-driver}/tsdown.config.ts (100%) rename packages/guard/{repeat-tool-guard => repeat-tool-reminder}/README.i18n.yaml (69%) rename packages/guard/{repeat-tool-guard => repeat-tool-reminder}/README.md (87%) rename packages/guard/{repeat-tool-guard => repeat-tool-reminder}/README.zh.md (87%) rename packages/guard/{repeat-tool-guard => repeat-tool-reminder}/package.json (93%) rename packages/guard/{repeat-tool-guard => repeat-tool-reminder}/src/index.ts (93%) rename packages/guard/{repeat-tool-guard => repeat-tool-reminder}/src/invariant.ts (83%) rename packages/guard/{repeat-tool-guard/tests/repeat-tool-guard.spec.ts => repeat-tool-reminder/tests/repeat-tool-reminder.spec.ts} (99%) rename packages/guard/{repeat-tool-guard => repeat-tool-reminder}/tsconfig.json (90%) rename packages/hooks/{hooks-claude => hooks-claude-code}/README.i18n.yaml (69%) rename packages/hooks/{hooks-claude => hooks-claude-code}/README.md (96%) rename packages/hooks/{hooks-claude => hooks-claude-code}/README.zh.md (96%) rename packages/hooks/{hooks-claude => hooks-claude-code}/package.json (93%) rename packages/hooks/{hooks-claude => hooks-claude-code}/src/config.ts (92%) rename packages/hooks/{hooks-claude => hooks-claude-code}/src/index.ts (92%) rename packages/hooks/{hooks-claude => hooks-claude-code}/src/invariant.ts (83%) rename packages/hooks/{hooks-claude => hooks-claude-code}/tests/bridge.spec.ts (95%) rename packages/hooks/{hooks-claude => hooks-claude-code}/tests/config.spec.ts (72%) rename packages/hooks/{hooks-claude => hooks-claude-code}/tests/coverage-cases.ts (95%) rename packages/hooks/{hooks-claude => hooks-claude-code}/tests/coverage-config.spec.ts (100%) rename packages/hooks/{hooks-claude => hooks-claude-code}/tests/coverage-context.spec.ts (100%) rename packages/hooks/{hooks-claude => hooks-claude-code}/tests/coverage-edge-paths.spec.ts (100%) rename packages/hooks/{hooks-claude => hooks-claude-code}/tests/coverage-stop.spec.ts (100%) rename packages/hooks/{hooks-claude => hooks-claude-code}/tsconfig.json (89%) rename packages/host/apiproxy/src/api/{tasks.schema.ts => jobs.schema.ts} (69%) rename packages/host/apiproxy/src/api/{tasks.ts => jobs.ts} (84%) rename packages/host/apiproxy/tests/{api-proxy-tasks.spec.ts => api-proxy-jobs.spec.ts} (74%) rename packages/{pty => identity}/README.i18n.yaml (57%) create mode 100644 packages/identity/README.md create mode 100644 packages/identity/README.zh.md create mode 100644 packages/identity/anonymous-user-id/README.i18n.yaml rename packages/{session/user-id => identity/anonymous-user-id}/README.md (78%) rename packages/{session/user-id => identity/anonymous-user-id}/README.zh.md (79%) rename packages/{session/user-id => identity/anonymous-user-id}/package.json (84%) rename packages/{session/user-id => identity/anonymous-user-id}/src/index.ts (93%) rename packages/{session/user-id => identity/anonymous-user-id}/src/invariant.ts (79%) rename packages/{session/user-id/tests/user-id.spec.ts => identity/anonymous-user-id/tests/anonymous-user-id.spec.ts} (81%) rename packages/{session/user-id => identity/anonymous-user-id}/tests/invariant.spec.ts (62%) rename packages/{session/user-id => identity/anonymous-user-id}/tsconfig.json (73%) rename packages/interaction/{user-interaction => permission-presets}/README.i18n.yaml (68%) create mode 100644 packages/interaction/permission-presets/README.md create mode 100644 packages/interaction/permission-presets/README.zh.md rename packages/interaction/{permission => permission-presets}/package.json (84%) rename packages/interaction/{permission => permission-presets}/src/client.ts (86%) rename packages/interaction/{permission => permission-presets}/src/index.ts (95%) rename packages/interaction/{permission => permission-presets}/src/invariant.ts (83%) rename packages/interaction/{permission => permission-presets}/src/types.ts (96%) rename packages/interaction/{permission => permission-presets}/tests/invariant.spec.ts (88%) rename packages/interaction/{permission/tests/permission.spec.ts => permission-presets/tests/permission-presets.spec.ts} (77%) rename packages/interaction/{permission => permission-presets}/tests/projection.spec.ts (92%) rename packages/interaction/{permission => permission-presets}/tsconfig.json (89%) delete mode 100644 packages/interaction/permission/README.md delete mode 100644 packages/interaction/permission/README.zh.md rename packages/interaction/{permission => user-questions}/README.i18n.yaml (69%) rename packages/interaction/{user-interaction => user-questions}/README.md (78%) rename packages/interaction/{user-interaction => user-questions}/README.zh.md (78%) rename packages/interaction/{user-interaction => user-questions}/package.json (85%) rename packages/interaction/{user-interaction => user-questions}/src/index.ts (74%) rename packages/interaction/{user-interaction => user-questions}/src/invariant.ts (84%) rename packages/interaction/{user-interaction => user-questions}/src/types.ts (95%) rename packages/interaction/{user-interaction/tests/user-interaction.spec.ts => user-questions/tests/user-questions.spec.ts} (66%) rename packages/interaction/{user-interaction => user-questions}/tsconfig.json (87%) rename packages/{bash => jobs}/README.i18n.yaml (59%) create mode 100644 packages/jobs/README.md create mode 100644 packages/jobs/README.zh.md rename packages/{bash/bash-local => jobs/jobs-local}/README.i18n.yaml (56%) create mode 100644 packages/jobs/jobs-local/README.md rename packages/{tasks/tasks-local => jobs/jobs-local}/README.zh.md (69%) rename packages/{tasks/tasks-local => jobs/jobs-local}/package.json (87%) rename packages/{tasks/tasks-local => jobs/jobs-local}/src/index.ts (61%) rename packages/{tasks/tasks-local => jobs/jobs-local}/src/invariant.ts (72%) rename packages/{tasks/tasks-local/tests/tasks.spec.ts => jobs/jobs-local/tests/jobs.spec.ts} (58%) rename packages/{tasks/tasks-local => jobs/jobs-local}/tests/loader-composition.spec.ts (75%) rename packages/{tasks/tasks-local => jobs/jobs-local}/tsconfig.json (86%) rename packages/{bash/bash => jobs/jobs}/README.i18n.yaml (57%) create mode 100644 packages/jobs/jobs/README.md rename packages/{tasks/tasks => jobs/jobs}/README.zh.md (52%) rename packages/{tasks/tasks => jobs/jobs}/package.json (83%) rename packages/{tasks/tasks => jobs/jobs}/src/brand.ts (57%) rename packages/{tasks/tasks => jobs/jobs}/src/index.ts (62%) rename packages/{tasks/tasks => jobs/jobs}/src/invariant.ts (57%) rename packages/{tasks/tasks => jobs/jobs}/src/types.ts (62%) rename packages/{tasks/tasks => jobs/jobs}/tests/invariant.spec.ts (57%) create mode 100644 packages/jobs/jobs/tests/service.spec.ts rename packages/{tasks/tasks => jobs/jobs}/tsconfig.json (89%) rename packages/{bash/bash-env => jobs/tool-jobs}/README.i18n.yaml (56%) create mode 100644 packages/jobs/tool-jobs/README.md rename packages/{tasks/tool-tasks => jobs/tool-jobs}/README.zh.md (57%) rename packages/{tasks/tool-tasks => jobs/tool-jobs}/package.json (75%) rename packages/{tasks/tool-tasks => jobs/tool-jobs}/src/index.ts (68%) rename packages/{tasks/tool-tasks => jobs/tool-jobs}/src/invariant.ts (85%) rename packages/{tasks/tool-tasks/tests/tool-tasks.spec.ts => jobs/tool-jobs/tests/tool-jobs.spec.ts} (71%) rename packages/{tasks/tool-tasks => jobs/tool-jobs}/tsconfig.json (81%) rename packages/lsp/{lsp-local => lsp-stdio}/README.i18n.yaml (71%) rename packages/lsp/{lsp-local => lsp-stdio}/README.md (99%) rename packages/lsp/{lsp-local => lsp-stdio}/README.zh.md (99%) rename packages/lsp/{lsp-local => lsp-stdio}/package.json (96%) rename packages/lsp/{lsp-local => lsp-stdio}/src/abort.ts (97%) rename packages/lsp/{lsp-local => lsp-stdio}/src/connection.ts (99%) rename packages/lsp/{lsp-local => lsp-stdio}/src/framing.ts (98%) rename packages/lsp/{lsp-local => lsp-stdio}/src/host.ts (100%) rename packages/lsp/{lsp-local => lsp-stdio}/src/index.ts (95%) rename packages/lsp/{lsp-local => lsp-stdio}/src/instance.ts (99%) rename packages/lsp/{lsp-local => lsp-stdio}/src/invariant.ts (80%) rename packages/lsp/{lsp-local => lsp-stdio}/src/protocol.ts (98%) rename packages/lsp/{lsp-local => lsp-stdio}/src/translate.ts (99%) rename packages/lsp/{lsp-local => lsp-stdio}/tests/built-lib.e2e.ts (93%) rename packages/lsp/{lsp-local => lsp-stdio}/tests/connection.spec.ts (98%) rename packages/lsp/{lsp-local => lsp-stdio}/tests/fixture-server.ts (99%) rename packages/lsp/{lsp-local => lsp-stdio}/tests/framing.spec.ts (99%) rename packages/lsp/{lsp-local => lsp-stdio}/tests/host.spec.ts (99%) rename packages/lsp/{lsp-local => lsp-stdio}/tests/instance.spec.ts (98%) rename packages/lsp/{lsp-local => lsp-stdio}/tests/lifecycle.spec.ts (97%) rename packages/lsp/{lsp-local => lsp-stdio}/tests/provider.spec.ts (92%) rename packages/lsp/{lsp-local => lsp-stdio}/tests/translate.spec.ts (99%) rename packages/lsp/{lsp-local => lsp-stdio}/tests/typescript-server.e2e.ts (95%) rename packages/lsp/{lsp-local => lsp-stdio}/tsconfig.json (92%) delete mode 100644 packages/pty/README.md delete mode 100644 packages/pty/README.zh.md delete mode 100644 packages/pty/pty-local/README.i18n.yaml delete mode 100644 packages/pty/tool-bash-persistent/README.i18n.yaml delete mode 100644 packages/pty/tool-pty/README.i18n.yaml delete mode 100644 packages/pty/tool-pty/README.md delete mode 100644 packages/pty/tool-pty/README.zh.md create mode 100644 packages/runtime-diagnostics/invariants/README.i18n.yaml rename packages/{support => runtime-diagnostics}/invariants/README.md (90%) rename packages/{support => runtime-diagnostics}/invariants/README.zh.md (90%) rename packages/{support => runtime-diagnostics}/invariants/package.json (94%) rename packages/{support => runtime-diagnostics}/invariants/src/index.ts (98%) rename packages/{support => runtime-diagnostics}/invariants/src/invariant.ts (100%) rename packages/{support => runtime-diagnostics}/invariants/tests/service.spec.ts (97%) rename packages/{support => runtime-diagnostics}/invariants/tsconfig.json (100%) rename packages/schedule/{tool-schedule => schedule}/README.i18n.yaml (69%) rename packages/schedule/{tool-schedule => schedule}/README.md (96%) rename packages/schedule/{tool-schedule => schedule}/README.zh.md (96%) rename packages/schedule/{tool-schedule => schedule}/package.json (95%) rename packages/schedule/{tool-schedule => schedule}/src/domain.ts (99%) rename packages/schedule/{tool-schedule => schedule}/src/index.ts (73%) rename packages/schedule/{tool-schedule => schedule}/src/invariant.ts (95%) rename packages/schedule/{tool-schedule => schedule}/src/persistence.ts (100%) rename packages/schedule/{tool-schedule => schedule}/src/runtime.ts (87%) rename packages/schedule/{tool-schedule => schedule}/src/tools.ts (98%) rename packages/schedule/{tool-schedule => schedule}/src/transaction.ts (100%) rename packages/schedule/{tool-schedule => schedule}/src/types.ts (99%) rename packages/schedule/{tool-schedule => schedule}/tests/domain.spec.ts (100%) rename packages/schedule/{tool-schedule => schedule}/tests/invariant.spec.ts (95%) rename packages/schedule/{tool-schedule => schedule}/tests/jsonl-restart.spec.ts (96%) rename packages/schedule/{tool-schedule => schedule}/tests/plugin.spec.ts (98%) rename packages/schedule/{tool-schedule => schedule}/tests/recurrence.spec.ts (100%) rename packages/schedule/{tool-schedule => schedule}/tests/runtime.spec.ts (84%) rename packages/schedule/{tool-schedule => schedule}/tests/tools.spec.ts (99%) rename packages/schedule/{tool-schedule => schedule}/tsconfig.json (92%) rename packages/schedule/{tool-schedule => schedule}/tsdown.config.ts (100%) delete mode 100644 packages/self-modification/tool-cordis/README.i18n.yaml delete mode 100644 packages/session-query/session-export/tsdown.config.ts rename packages/session-query/{session-export => session-log-download}/README.i18n.yaml (67%) rename packages/session-query/{session-export => session-log-download}/README.md (87%) rename packages/session-query/{session-export => session-log-download}/README.zh.md (86%) rename packages/session-query/{session-export => session-log-download}/package.json (88%) rename packages/session-query/{session-export => session-log-download}/src/client/Dialog.tsx (75%) rename packages/session-query/{session-export => session-log-download}/src/client/HeaderAction.module.css (100%) rename packages/session-query/{session-export => session-log-download}/src/client/HeaderAction.tsx (66%) rename packages/session-query/{session-export => session-log-download}/src/client/controller.ts (89%) rename packages/session-query/{session-export => session-log-download}/src/client/index.ts (57%) rename packages/session-query/{session-export => session-log-download}/src/client/locales.ts (92%) rename packages/session-query/{session-export => session-log-download}/src/css-modules.d.ts (100%) rename packages/session-query/{session-export => session-log-download}/src/index.ts (91%) rename packages/session-query/{session-export => session-log-download}/src/invariant.ts (83%) rename packages/session-query/{session-export => session-log-download}/tests/client-apply.client.spec.tsx (70%) rename packages/session-query/{session-export => session-log-download}/tests/command.client.spec.ts (91%) rename packages/session-query/{session-export => session-log-download}/tests/controller.client.spec.ts (86%) rename packages/session-query/{session-export => session-log-download}/tests/dialog.client.spec.tsx (79%) rename packages/session-query/{session-export => session-log-download}/tests/header-action.client.spec.tsx (69%) rename packages/session-query/{session-export => session-log-download}/tests/invariant.client.spec.ts (83%) rename packages/session-query/{session-export => session-log-download}/tests/loader-composition.client.spec.ts (87%) rename packages/session-query/{session-export => session-log-download}/tsconfig.json (83%) create mode 100644 packages/session-query/session-log-download/tsdown.config.ts rename packages/session/{user-id => session-title-all-prompts-llm}/README.i18n.yaml (67%) rename packages/session/{session-title-all-messages-llm => session-title-all-prompts-llm}/README.md (80%) rename packages/session/{session-title-all-messages-llm => session-title-all-prompts-llm}/README.zh.md (81%) rename packages/session/{session-title-all-messages-llm => session-title-all-prompts-llm}/package.json (91%) rename packages/session/{session-title-all-messages-llm => session-title-all-prompts-llm}/src/index.ts (83%) rename packages/session/{session-title-first-message-llm => session-title-all-prompts-llm}/src/invariant.ts (79%) rename packages/session/{session-title-all-messages-llm => session-title-all-prompts-llm}/tests/provider.spec.ts (96%) rename packages/session/{session-title-first-message-llm => session-title-all-prompts-llm}/tsconfig.json (87%) delete mode 100644 packages/session/session-title-first-message-llm/README.i18n.yaml rename packages/session/{session-title-all-messages-llm => session-title-first-prompt-llm}/README.i18n.yaml (67%) rename packages/session/{session-title-first-message-llm => session-title-first-prompt-llm}/README.md (82%) rename packages/session/{session-title-first-message-llm => session-title-first-prompt-llm}/README.zh.md (80%) rename packages/session/{session-title-first-message-llm => session-title-first-prompt-llm}/package.json (92%) rename packages/session/{session-title-first-message-llm => session-title-first-prompt-llm}/src/index.ts (83%) rename packages/session/{session-title-all-messages-llm => session-title-first-prompt-llm}/src/invariant.ts (80%) rename packages/session/{session-title-first-message-llm => session-title-first-prompt-llm}/tests/loader-composition.spec.ts (92%) rename packages/session/{session-title-first-message-llm => session-title-first-prompt-llm}/tests/provider.e2e.ts (87%) rename packages/session/{session-title-first-message-llm => session-title-first-prompt-llm}/tests/provider.spec.ts (94%) rename packages/session/{session-title-all-messages-llm => session-title-first-prompt-llm}/tsconfig.json (87%) rename packages/settings/{settings-local => settings-file}/README.i18n.yaml (69%) rename packages/settings/{settings-local => settings-file}/README.md (99%) rename packages/settings/{settings-local => settings-file}/README.zh.md (99%) rename packages/settings/{settings-local => settings-file}/package.json (87%) rename packages/settings/{settings-local => settings-file}/src/index.ts (94%) rename packages/settings/{settings-local => settings-file}/src/invariant.ts (85%) rename packages/settings/{settings-local => settings-file}/tests/concurrency.spec.ts (95%) rename packages/settings/{settings-local => settings-file}/tests/loader-composition.spec.ts (95%) rename packages/settings/{settings-local => settings-file}/tests/local.spec.ts (98%) rename packages/settings/{settings-local => settings-file}/tests/lock-race.spec.ts (94%) rename packages/settings/{settings-local => settings-file}/tests/watcher.spec.ts (96%) rename packages/settings/{settings-local => settings-file}/tsconfig.json (83%) rename packages/{tasks => shell}/README.i18n.yaml (59%) rename packages/{bash => shell}/README.md (71%) rename packages/{bash => shell}/README.zh.md (69%) create mode 100644 packages/shell/bash-local/README.i18n.yaml rename packages/{bash => shell}/bash-local/README.md (68%) rename packages/{bash => shell}/bash-local/README.zh.md (68%) rename packages/{bash => shell}/bash-local/package.json (91%) rename packages/{bash => shell}/bash-local/src/index.ts (93%) rename packages/{bash => shell}/bash-local/src/invariant.ts (100%) rename packages/{bash => shell}/bash-local/tests/executor.spec.ts (94%) rename packages/{bash => shell}/bash-local/tests/settings.spec.ts (75%) rename packages/{bash => shell}/bash-local/tsconfig.json (86%) create mode 100644 packages/shell/bash-sandbox/README.i18n.yaml rename packages/{bash => shell}/bash-sandbox/README.md (82%) rename packages/{bash => shell}/bash-sandbox/README.zh.md (82%) rename packages/{bash => shell}/bash-sandbox/package.json (92%) rename packages/{bash => shell}/bash-sandbox/src/helpers.ts (96%) rename packages/{bash => shell}/bash-sandbox/src/index.ts (91%) rename packages/{bash => shell}/bash-sandbox/src/invariant.ts (100%) rename packages/{bash => shell}/bash-sandbox/tests/bwrap.e2e.ts (96%) rename packages/{bash => shell}/bash-sandbox/tests/landlock.e2e.ts (96%) rename packages/{bash => shell}/bash-sandbox/tests/partial-landlock.spec.ts (98%) rename packages/{bash => shell}/bash-sandbox/tests/sandbox.spec.ts (97%) rename packages/{bash => shell}/bash-sandbox/tests/seatbelt.e2e.ts (96%) rename packages/{bash => shell}/bash-sandbox/tsconfig.json (82%) create mode 100644 packages/shell/pwsh-local/README.i18n.yaml rename packages/{bash => shell}/pwsh-local/README.md (75%) rename packages/{bash => shell}/pwsh-local/README.zh.md (77%) rename packages/{bash => shell}/pwsh-local/package.json (91%) rename packages/{bash => shell}/pwsh-local/src/index.ts (93%) rename packages/{bash => shell}/pwsh-local/src/invariant.ts (100%) rename packages/{bash => shell}/pwsh-local/src/resolve.ts (100%) rename packages/{bash => shell}/pwsh-local/tests/executor.spec.ts (95%) rename packages/{bash => shell}/pwsh-local/tests/settings.spec.ts (78%) rename packages/{bash => shell}/pwsh-local/tsconfig.json (86%) create mode 100644 packages/shell/pwsh-sandbox/README.i18n.yaml rename packages/{bash => shell}/pwsh-sandbox/README.md (75%) rename packages/{bash => shell}/pwsh-sandbox/README.zh.md (74%) rename packages/{bash => shell}/pwsh-sandbox/package.json (91%) rename packages/{bash => shell}/pwsh-sandbox/src/helpers.ts (97%) rename packages/{bash => shell}/pwsh-sandbox/src/index.ts (91%) rename packages/{bash => shell}/pwsh-sandbox/src/invariant.ts (100%) rename packages/{bash => shell}/pwsh-sandbox/tests/acl.e2e.ts (97%) rename packages/{bash => shell}/pwsh-sandbox/tests/sandbox.spec.ts (97%) rename packages/{bash => shell}/pwsh-sandbox/tsconfig.json (80%) create mode 100644 packages/shell/shell-env/README.i18n.yaml create mode 100644 packages/shell/shell-env/README.md create mode 100644 packages/shell/shell-env/README.zh.md rename packages/{bash/bash-env => shell/shell-env}/package.json (83%) rename packages/{bash/bash-env => shell/shell-env}/src/index.ts (90%) rename packages/{bash/bash-env => shell/shell-env}/src/invariant.ts (81%) rename packages/{bash/bash-env/tests/bash-env.spec.ts => shell/shell-env/tests/shell-env.spec.ts} (84%) rename packages/{bash/bash-env => shell/shell-env}/tsconfig.json (79%) create mode 100644 packages/shell/shell/README.i18n.yaml rename packages/{bash/bash => shell/shell}/README.md (50%) create mode 100644 packages/shell/shell/README.zh.md rename packages/{bash/bash => shell/shell}/package.json (88%) rename packages/{bash/bash => shell/shell}/src/index.ts (70%) rename packages/{bash/bash => shell/shell}/src/invariant.ts (87%) rename packages/{bash/bash => shell/shell}/src/render.ts (93%) rename packages/{bash/bash => shell/shell}/src/types.ts (85%) rename packages/{bash/bash => shell/shell}/tests/render.spec.ts (100%) rename packages/{bash/bash => shell/shell}/tests/service.spec.ts (66%) rename packages/{bash/bash => shell/shell}/tsconfig.json (89%) create mode 100644 packages/shell/tool-bash-persistent/README.i18n.yaml rename packages/{pty => shell}/tool-bash-persistent/README.md (93%) rename packages/{pty => shell}/tool-bash-persistent/README.zh.md (95%) rename packages/{pty => shell}/tool-bash-persistent/package.json (89%) rename packages/{pty => shell}/tool-bash-persistent/src/index.ts (91%) rename packages/{pty => shell}/tool-bash-persistent/src/invariant.ts (100%) rename packages/{pty => shell}/tool-bash-persistent/tests/loader-composition.spec.ts (91%) rename packages/{pty => shell}/tool-bash-persistent/tests/tools.spec.ts (94%) rename packages/{pty => shell}/tool-bash-persistent/tsconfig.json (76%) create mode 100644 packages/shell/tool-bash/README.i18n.yaml rename packages/{bash => shell}/tool-bash/README.md (60%) rename packages/{bash => shell}/tool-bash/README.zh.md (61%) rename packages/{bash => shell}/tool-bash/package.json (81%) rename packages/{bash => shell}/tool-bash/src/background.ts (75%) rename packages/{bash => shell}/tool-bash/src/index.ts (91%) rename packages/{bash => shell}/tool-bash/src/invariant.ts (100%) rename packages/{bash => shell}/tool-bash/src/render.ts (90%) rename packages/{bash => shell}/tool-bash/tests/integration.spec.ts (91%) rename packages/{bash => shell}/tool-bash/tests/tools.spec.ts (90%) rename packages/{bash => shell}/tool-bash/tsconfig.json (82%) create mode 100644 packages/shell/tool-pwsh/README.i18n.yaml rename packages/{bash => shell}/tool-pwsh/README.md (66%) rename packages/{bash => shell}/tool-pwsh/README.zh.md (69%) rename packages/{bash => shell}/tool-pwsh/package.json (82%) rename packages/{bash => shell}/tool-pwsh/src/background.ts (79%) rename packages/{bash => shell}/tool-pwsh/src/index.ts (92%) rename packages/{bash => shell}/tool-pwsh/src/invariant.ts (100%) rename packages/{bash => shell}/tool-pwsh/src/render.ts (94%) rename packages/{bash => shell}/tool-pwsh/tests/integration.spec.ts (88%) rename packages/{bash => shell}/tool-pwsh/tests/loader.spec.ts (94%) rename packages/{bash => shell}/tool-pwsh/tests/tools.spec.ts (90%) rename packages/{bash => shell}/tool-pwsh/tsconfig.json (79%) rename packages/skill/{skill-local => skill-filesystem}/README.i18n.yaml (69%) rename packages/skill/{skill-local => skill-filesystem}/README.md (97%) rename packages/skill/{skill-local => skill-filesystem}/README.zh.md (96%) rename packages/skill/{skill-local => skill-filesystem}/package.json (86%) rename packages/skill/{skill-local => skill-filesystem}/src/index.ts (97%) rename packages/skill/{skill-local => skill-filesystem}/src/invariant.ts (83%) rename packages/skill/{skill-local/tests/skill-local-watcher.spec.ts => skill-filesystem/tests/skill-filesystem-watcher.spec.ts} (90%) rename packages/skill/{skill-local/tests/skill-local.spec.ts => skill-filesystem/tests/skill-filesystem.spec.ts} (93%) rename packages/skill/{skill-local => skill-filesystem}/tsconfig.json (78%) rename packages/subagent/{subagent-fork => subagent-fork-in-process}/README.i18n.yaml (68%) rename packages/subagent/{subagent-fork => subagent-fork-in-process}/README.md (91%) rename packages/subagent/{subagent-fork => subagent-fork-in-process}/README.zh.md (92%) rename packages/subagent/{subagent-fork => subagent-fork-in-process}/package.json (83%) rename packages/subagent/{subagent-fork => subagent-fork-in-process}/src/index.ts (92%) rename packages/subagent/{subagent-inprocess => subagent-fork-in-process}/src/invariant.ts (81%) rename packages/subagent/{subagent-fork => subagent-fork-in-process}/tests/multi-subagent.spec.ts (95%) rename packages/subagent/{subagent-fork/tests/subagent-fork.spec.ts => subagent-fork-in-process/tests/subagent-fork-in-process.spec.ts} (96%) rename packages/subagent/{subagent-fork => subagent-fork-in-process}/tsconfig.json (83%) rename packages/subagent/{subagent-spawn => subagent-in-process-driver}/README.i18n.yaml (67%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/README.md (99%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/README.zh.md (99%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/package.json (94%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/src/index.ts (99%) rename packages/subagent/{subagent-fork => subagent-in-process-driver}/src/invariant.ts (80%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/src/structured.ts (98%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/tests/fixtures/plugins/preset-tool.js (100%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/tests/fixtures/presets/coding/agent.cordis.yml (100%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/tests/fixtures/presets/reviewing/agent.cordis.yml (100%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/tests/inheritance.spec.ts (100%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/tests/preset-inheritance.spec.ts (100%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/tests/structured.spec.ts (99%) rename packages/subagent/{subagent-inprocess/tests/subagent-inprocess.spec.ts => subagent-in-process-driver/tests/subagent-in-process-driver.spec.ts} (98%) rename packages/subagent/{subagent-inprocess => subagent-in-process-driver}/tsconfig.json (91%) rename packages/subagent/{subagent-inprocess => subagent-spawn-in-process}/README.i18n.yaml (67%) rename packages/subagent/{subagent-spawn => subagent-spawn-in-process}/README.md (90%) rename packages/subagent/{subagent-spawn => subagent-spawn-in-process}/README.zh.md (90%) rename packages/subagent/{subagent-spawn => subagent-spawn-in-process}/package.json (87%) rename packages/subagent/{subagent-spawn => subagent-spawn-in-process}/src/index.ts (87%) rename packages/subagent/{subagent-spawn => subagent-spawn-in-process}/src/invariant.ts (81%) rename packages/subagent/{subagent-spawn => subagent-spawn-in-process}/tests/harness.ts (88%) rename packages/subagent/{subagent-spawn/tests/spawn.e2e.ts => subagent-spawn-in-process/tests/spawn-in-process.e2e.ts} (100%) rename packages/subagent/{subagent-spawn/tests/subagent-spawn.spec.ts => subagent-spawn-in-process/tests/subagent-spawn-in-process.spec.ts} (97%) rename packages/subagent/{subagent-spawn => subagent-spawn-in-process}/tsconfig.json (80%) delete mode 100644 packages/support/README.i18n.yaml delete mode 100644 packages/support/invariants/README.i18n.yaml delete mode 100644 packages/support/llm-replay/README.i18n.yaml delete mode 100644 packages/tasks/README.md delete mode 100644 packages/tasks/README.zh.md delete mode 100644 packages/tasks/tasks-local/README.i18n.yaml delete mode 100644 packages/tasks/tasks-local/README.md delete mode 100644 packages/tasks/tasks/README.i18n.yaml delete mode 100644 packages/tasks/tasks/README.md delete mode 100644 packages/tasks/tasks/tests/service.spec.ts delete mode 100644 packages/tasks/tool-tasks/README.i18n.yaml delete mode 100644 packages/tasks/tool-tasks/README.md rename packages/{pty/pty => terminal}/README.i18n.yaml (57%) create mode 100644 packages/terminal/README.md create mode 100644 packages/terminal/README.zh.md create mode 100644 packages/terminal/terminal-bash/README.i18n.yaml rename packages/{pty/pty-local => terminal/terminal-bash}/README.md (78%) rename packages/{pty/pty-local => terminal/terminal-bash}/README.zh.md (79%) rename packages/{pty/pty-local => terminal/terminal-bash}/package.json (89%) rename packages/{pty/pty-local => terminal/terminal-bash}/src/config.ts (84%) rename packages/{pty/pty-local => terminal/terminal-bash}/src/index.ts (82%) rename packages/{pty/pty-local => terminal/terminal-bash}/src/invariant.ts (79%) rename packages/{pty/pty-local => terminal/terminal-bash}/src/sanitize.ts (100%) rename packages/{pty/pty-local => terminal/terminal-bash}/src/session.ts (93%) rename packages/{pty/pty-local => terminal/terminal-bash}/tests/config.spec.ts (87%) rename packages/{pty/pty-local => terminal/terminal-bash}/tests/index.spec.ts (86%) rename packages/{pty/pty-local => terminal/terminal-bash}/tests/local.spec.ts (75%) rename packages/{pty/pty-local => terminal/terminal-bash}/tests/sanitize.spec.ts (98%) rename packages/{pty/pty-local => terminal/terminal-bash}/tests/session.spec.ts (96%) rename packages/{pty/pty-local => terminal/terminal-bash}/tsconfig.json (88%) rename packages/{bash/bash-sandbox => terminal/terminal}/README.i18n.yaml (55%) rename packages/{pty/pty => terminal/terminal}/README.md (71%) rename packages/{pty/pty => terminal/terminal}/README.zh.md (70%) rename packages/{pty/pty => terminal/terminal}/package.json (93%) rename packages/{pty/pty => terminal/terminal}/src/index.ts (75%) rename packages/{pty/pty => terminal/terminal}/src/invariant.ts (81%) rename packages/{pty/pty => terminal/terminal}/src/types.ts (71%) rename packages/{pty/pty => terminal/terminal}/tests/service.spec.ts (67%) rename packages/{pty/pty => terminal/terminal}/tsconfig.json (87%) create mode 100644 packages/terminal/tool-terminal/README.i18n.yaml create mode 100644 packages/terminal/tool-terminal/README.md create mode 100644 packages/terminal/tool-terminal/README.zh.md rename packages/{pty/tool-pty => terminal/tool-terminal}/package.json (74%) rename packages/{pty/tool-pty => terminal/tool-terminal}/src/index.ts (85%) rename packages/{pty/tool-pty => terminal/tool-terminal}/src/invariant.ts (77%) rename packages/{pty/tool-pty => terminal/tool-terminal}/src/render.ts (97%) rename packages/{pty/tool-pty => terminal/tool-terminal}/tests/loader-composition.spec.ts (84%) rename packages/{pty/tool-pty => terminal/tool-terminal}/tests/render.spec.ts (74%) rename packages/{pty/tool-pty => terminal/tool-terminal}/tests/tools.spec.ts (89%) rename packages/{pty/tool-pty => terminal/tool-terminal}/tsconfig.json (76%) rename packages/{fs/fs-policy => test-support}/README.i18n.yaml (56%) rename packages/{support => test-support}/README.md (75%) rename packages/{support => test-support}/README.zh.md (83%) rename packages/{support => test-support}/acp-snapshot/README.i18n.yaml (79%) rename packages/{support => test-support}/acp-snapshot/README.md (100%) rename packages/{support => test-support}/acp-snapshot/README.zh.md (100%) rename packages/{support => test-support}/acp-snapshot/package.json (96%) rename packages/{support => test-support}/acp-snapshot/src/harness.ts (100%) rename packages/{support => test-support}/acp-snapshot/src/index.ts (100%) rename packages/{support => test-support}/acp-snapshot/src/invariant.ts (100%) rename packages/{support => test-support}/acp-snapshot/src/launcher.ts (100%) rename packages/{support => test-support}/acp-snapshot/src/normalize.ts (100%) rename packages/{support => test-support}/acp-snapshot/src/suite.ts (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/fake-acp-agent.ts (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-child/behavior.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-child/input.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-child/session.1.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-child/session.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-child/stdout.expected.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-pin/behavior.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-pin/input.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-pin/session.1.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-pin/session.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-pin/stdout.expected.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-pin/system-prompt.expected.md (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-pin/tool-schemas.expected.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-skip/behavior.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-skip/input.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-skip/replay.override.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-skip/session.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/record-suite/rec-skip/stdout.expected.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/authored-error/behavior.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/authored-error/input.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/authored-error/replay.override.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/authored-error/session.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/authored-error/stdout.expected.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/blocked-log/behavior.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/blocked-log/input.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/blocked-log/session.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/blocked-log/stdout.expected.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/no-model/behavior.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/no-model/input.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/no-model/session.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/no-model/stdout.expected.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/pin-turn/behavior.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/pin-turn/input.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/pin-turn/session.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/pin-turn/stdout.expected.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/pin-turn/system-prompt.expected.md (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/pin-turn/tool-schemas.expected.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/plain-turn/behavior.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/plain-turn/input.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/plain-turn/session.1.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/plain-turn/session.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/plain-turn/stdout.expected.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/plain-turn/system-prompt.1.expected.md (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/plain-turn/tool-schemas.1.expected.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/plain-turn/workspace/seed.txt (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/shared-pin/behavior.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/shared-pin/input.json (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/shared-pin/session.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/fixtures/suite/shared-pin/stdout.expected.jsonl (100%) rename packages/{support => test-support}/acp-snapshot/tests/harness.spec.ts (100%) rename packages/{support => test-support}/acp-snapshot/tests/normalize.spec.ts (100%) rename packages/{support => test-support}/acp-snapshot/tests/suite.spec.ts (100%) rename packages/{support => test-support}/acp-snapshot/tsconfig.json (84%) rename packages/{support => test-support}/agent-loop-testkit/README.i18n.yaml (78%) rename packages/{support => test-support}/agent-loop-testkit/README.md (100%) rename packages/{support => test-support}/agent-loop-testkit/README.zh.md (100%) rename packages/{support => test-support}/agent-loop-testkit/package.json (96%) rename packages/{support => test-support}/agent-loop-testkit/src/index.ts (85%) rename packages/{support => test-support}/agent-loop-testkit/src/invariant.ts (100%) rename packages/{support => test-support}/agent-loop-testkit/tests/agent-loop-testkit.spec.ts (100%) rename packages/{support => test-support}/agent-loop-testkit/tsconfig.json (90%) create mode 100644 packages/test-support/client-runtime/README.i18n.yaml rename packages/{client/test-runtime => test-support/client-runtime}/README.md (87%) rename packages/{client/test-runtime => test-support/client-runtime}/README.zh.md (84%) rename packages/{client/test-runtime => test-support/client-runtime}/package.json (93%) rename packages/{client/test-runtime => test-support/client-runtime}/src/fixtures.ts (99%) rename packages/{client/test-runtime => test-support/client-runtime}/src/index.ts (96%) rename packages/{client/test-runtime => test-support/client-runtime}/src/invariant.ts (93%) rename packages/{client/test-runtime => test-support/client-runtime}/src/locale-env.ts (95%) rename packages/{client/test-runtime => test-support/client-runtime}/src/remote.ts (100%) rename packages/{client/test-runtime => test-support/client-runtime}/src/sessions.ts (98%) rename packages/{client/test-runtime => test-support/client-runtime}/src/settings-scope.ts (100%) rename packages/{client/test-runtime => test-support/client-runtime}/src/snapshot.ts (100%) rename packages/{client/test-runtime => test-support/client-runtime}/src/translate.ts (94%) rename packages/{client/test-runtime => test-support/client-runtime}/src/workspaces.ts (100%) rename packages/{client/test-runtime => test-support/client-runtime}/tests/__snapshots__/runtime.client.spec.tsx.snap (100%) rename packages/{client/test-runtime => test-support/client-runtime}/tests/invariant.client.spec.ts (77%) rename packages/{client/test-runtime => test-support/client-runtime}/tests/remote.client.spec.ts (100%) rename packages/{client/test-runtime => test-support/client-runtime}/tests/runtime.client.spec.tsx (99%) rename packages/{client/test-runtime => test-support/client-runtime}/tsconfig.json (66%) rename packages/{client/test-runtime => test-support/client-runtime}/tsdown.config.ts (67%) rename packages/{support => test-support}/llm-mock-server/README.i18n.yaml (78%) rename packages/{support => test-support}/llm-mock-server/README.md (100%) rename packages/{support => test-support}/llm-mock-server/README.zh.md (100%) rename packages/{support => test-support}/llm-mock-server/package.json (94%) rename packages/{support => test-support}/llm-mock-server/src/bin.ts (100%) rename packages/{support => test-support}/llm-mock-server/src/cli.ts (100%) rename packages/{support => test-support}/llm-mock-server/src/index.ts (100%) rename packages/{support => test-support}/llm-mock-server/src/invariant.ts (100%) rename packages/{support => test-support}/llm-mock-server/tests/cli.spec.ts (100%) rename packages/{support => test-support}/llm-mock-server/tests/invariant.spec.ts (84%) rename packages/{support => test-support}/llm-mock-server/tests/server.spec.ts (100%) rename packages/{util/paths => test-support/llm-mock-server}/tsconfig.json (78%) rename packages/{support => test-support}/llm-mock-server/tsdown.config.ts (100%) create mode 100644 packages/test-support/llm-replay/README.i18n.yaml rename packages/{support => test-support}/llm-replay/README.md (93%) rename packages/{support => test-support}/llm-replay/README.zh.md (93%) rename packages/{support => test-support}/llm-replay/package.json (89%) rename packages/{support => test-support}/llm-replay/src/index.ts (98%) rename packages/{support => test-support}/llm-replay/src/invariant.ts (100%) rename packages/{support => test-support}/llm-replay/tests/llm-replay.spec.ts (96%) rename packages/{support => test-support}/llm-replay/tsconfig.json (80%) rename packages/{support => test-support}/loader-smoke/README.i18n.yaml (79%) rename packages/{support => test-support}/loader-smoke/README.md (100%) rename packages/{support => test-support}/loader-smoke/README.zh.md (100%) rename packages/{support => test-support}/loader-smoke/package.json (96%) rename packages/{support => test-support}/loader-smoke/src/agent-turn.ts (100%) rename packages/{support => test-support}/loader-smoke/src/index.ts (100%) rename packages/{support => test-support}/loader-smoke/src/invariant.ts (100%) rename packages/{support => test-support}/loader-smoke/tests/agent-turn.spec.ts (100%) rename packages/{support => test-support}/loader-smoke/tests/example-launch.spec.ts (100%) rename packages/{support => test-support}/loader-smoke/tests/fixtures/fail.ts (100%) rename packages/{support => test-support}/loader-smoke/tests/fixtures/hang.ts (100%) rename packages/{support => test-support}/loader-smoke/tests/fixtures/success.ts (100%) rename packages/{support => test-support}/loader-smoke/tests/loader-smoke.spec.ts (100%) rename packages/{support => test-support}/loader-smoke/tsconfig.json (85%) rename packages/typert/generator/tests/fixtures/remote-model/{type-meta.d.ts => typert-protocol.d.ts} (66%) rename packages/typert/{type-meta => protocol}/README.i18n.yaml (70%) rename packages/typert/{type-meta => protocol}/README.md (72%) rename packages/typert/{type-meta => protocol}/README.zh.md (71%) rename packages/typert/{type-meta => protocol}/package.json (85%) rename packages/typert/{type-meta => protocol}/src/index.ts (76%) rename packages/typert/{type-meta => protocol}/src/invariant.ts (78%) rename packages/typert/{type-meta => protocol}/src/types.ts (76%) rename packages/typert/{type-meta => protocol}/tests/fixtures/source-launch.ts (86%) rename packages/typert/{type-meta/tests/type-meta.spec.ts => protocol/tests/protocol.spec.ts} (83%) rename packages/typert/{type-meta => protocol}/tsconfig.json (84%) delete mode 100644 packages/util/environment/README.i18n.yaml create mode 100644 packages/util/home-paths/README.i18n.yaml rename packages/util/{paths => home-paths}/README.md (99%) rename packages/util/{paths => home-paths}/README.zh.md (99%) rename packages/util/{paths => home-paths}/package.json (92%) rename packages/util/{paths => home-paths}/src/index.ts (99%) rename packages/util/{retention => home-paths}/src/invariant.ts (79%) rename packages/util/{paths/tests/paths.spec.ts => home-paths/tests/home-paths.spec.ts} (98%) rename packages/util/{retention => home-paths}/tsconfig.json (78%) create mode 100644 packages/util/launch-environment/README.i18n.yaml rename packages/util/{environment => launch-environment}/README.md (83%) rename packages/util/{environment => launch-environment}/README.zh.md (82%) rename packages/util/{environment => launch-environment}/package.json (91%) rename packages/util/{environment => launch-environment}/src/index.ts (71%) rename packages/util/{environment => launch-environment}/src/invariant.ts (78%) rename packages/util/{environment/tests/environment.spec.ts => launch-environment/tests/launch-environment.spec.ts} (80%) rename packages/util/{environment => launch-environment}/tsconfig.json (78%) create mode 100644 packages/util/output-retention/README.i18n.yaml rename packages/util/{retention => output-retention}/README.md (98%) rename packages/util/{retention => output-retention}/README.zh.md (98%) rename packages/util/{retention => output-retention}/package.json (91%) rename packages/util/{retention => output-retention}/src/index.ts (99%) rename packages/util/{paths => output-retention}/src/invariant.ts (77%) rename packages/util/{retention/tests/retention.spec.ts => output-retention/tests/output-retention.spec.ts} (99%) rename packages/{support/llm-mock-server => util/output-retention}/tsconfig.json (78%) delete mode 100644 packages/util/paths/README.i18n.yaml delete mode 100644 packages/util/retention/README.i18n.yaml rename packages/web/{web-fetch-local => web-fetch-http}/README.i18n.yaml (70%) rename packages/web/{web-fetch-local => web-fetch-http}/README.md (93%) rename packages/web/{web-fetch-local => web-fetch-http}/README.zh.md (92%) rename packages/web/{web-fetch-local => web-fetch-http}/package.json (93%) rename packages/web/{web-fetch-local => web-fetch-http}/src/index.ts (82%) rename packages/web/{web-fetch-local => web-fetch-http}/src/invariant.ts (84%) rename packages/web/{web-fetch-local => web-fetch-http}/src/policy.ts (98%) rename packages/web/{web-fetch-local => web-fetch-http}/src/provider.ts (97%) rename packages/web/{web-fetch-local/tests/fetch-local.spec.ts => web-fetch-http/tests/fetch-http.spec.ts} (94%) rename packages/web/{web-fetch-local => web-fetch-http}/tsconfig.json (89%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/README.i18n.yaml (68%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/README.md (96%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/README.zh.md (96%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/package.json (92%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/src/host.ts (98%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/src/index.ts (96%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/src/invariant.ts (82%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/src/meta.ts (98%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/src/protocol.ts (98%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/src/realm.ts (99%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/src/runtime.ts (99%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/src/session.ts (99%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/src/types.ts (98%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/src/worker.ts (91%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/tests/built-worker.e2e.ts (89%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/tests/integration.spec.ts (88%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/tests/meta.spec.ts (100%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/tests/realm.spec.ts (100%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/tests/session.spec.ts (100%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/tests/source-worker.compat.spec.ts (85%) rename packages/workflow/{workflow-workerthread/tests/workflow-workerthread.e2e.ts => workflow-worker-thread/tests/workflow-worker-thread.e2e.ts} (87%) rename packages/workflow/{workflow-workerthread/tests/workflow-workerthread.spec.ts => workflow-worker-thread/tests/workflow-worker-thread.spec.ts} (92%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/tsconfig.json (92%) rename packages/workflow/{workflow-workerthread => workflow-worker-thread}/tsdown.config.ts (100%) diff --git a/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.i18n.yaml index 3d34ff3934..760c3fd099 100644 --- a/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.i18n.yaml @@ -2,5 +2,5 @@ # 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 .agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.md -2026-06-11-event-sourced-sessions.md: 1303ee843cd5f9e02eae7a1f9bc51594be4bb407 -2026-06-11-event-sourced-sessions.zh.md: 4308251ddc4564fc0547230d10671b6595389a1a +2026-06-11-event-sourced-sessions.md: b6d17d2db1d9b489f3d4224683b61e62be485014 +2026-06-11-event-sourced-sessions.zh.md: a78349ea2385b3c9d32870757bb607f15996196d diff --git a/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.md b/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.md index 1303ee843c..b6d17d2db1 100644 --- a/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.md +++ b/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.md @@ -25,4 +25,4 @@ Ordering contract: the loop claims inbox messages before `agent/pre-step`, opens - Replay, trace, and telemetry are structurally guaranteed, not bolted on. - Persistence stays a plugin concern; the in-memory store ships in dsh-session. - The event vocabulary is merge-extensible (plugins add e.g. compaction events); [session persistence](2026-06-14-session-persistence.md) froze its shape once the log became durable. -- Derivation cost grows with log length — compaction (dsh-compact) is the intended mitigation, not log mutation. +- Derivation cost grows with log length — compaction (dsh-compaction) is the intended mitigation, not log mutation. diff --git a/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.zh.md b/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.zh.md index 4308251ddc..a78349ea23 100644 --- a/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.zh.md +++ b/.agents/notes/implemented/architecture/2026-06-11-event-sourced-sessions.zh.md @@ -25,4 +25,4 @@ MVP 要求严格的基于事件的追踪,以及完全可回放的会话(严 - 回放、追踪与遥测在结构上得到保证,而非事后附加。 - 持久化仍是插件关注点;内存存储随 dsh-session 一起提供。 - 事件词汇可通过合并扩展(插件可添加如压缩(compaction)事件);[会话持久化](2026-06-14-session-persistence.md)在日志具备持久性后固定了其结构。 -- 派生成本随日志长度增长,压缩(dsh-compact)是预期的缓解手段,而不是改写日志。 +- 派生成本随日志长度增长,压缩(dsh-compaction)是预期的缓解手段,而不是改写日志。 diff --git a/.agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml index cc21a54254..f07afccac7 100644 --- a/.agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-13-capability-seams.i18n.yaml @@ -2,5 +2,5 @@ # 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 .agents/notes/implemented/architecture/2026-06-13-capability-seams.md -2026-06-13-capability-seams.md: b2dc124f7bf0b56598466e6521e0764af06075ab -2026-06-13-capability-seams.zh.md: 79befde57392888dd6a07236379b0155b68d2f01 +2026-06-13-capability-seams.md: efb000631c6dfe91ab648b102a14a27c30d790b4 +2026-06-13-capability-seams.zh.md: bf6571dfa5c3a90f856480bc22c6560ed65b3e77 diff --git a/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md b/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md index b2dc124f7b..efb000631c 100644 --- a/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md +++ b/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md @@ -8,15 +8,15 @@ English | [中文](2026-06-13-capability-seams.zh.md) The harness has swappable capabilities — bash execution today, sandboxed/remote executors and alternative model providers tomorrow. A capability has three concerns that change at different rates and for different reasons: the *contract* (what the capability is), the *implementation* (how it runs), and the *consumer API* (what the model and other plugins program against). Bundling them in one package couples those rates of change — swapping a local executor for a sandboxed one would churn the tool schemas the model sees, even though the model-facing contract never changed. -This is distinct from "who provides vs. needs a capability at runtime", which Cordis already answers with services + `inject` (a provider registers `ctx.bash`; a consumer declares `inject: ['bash']` and its fiber pends until the service exists). That mechanism is necessary but doesn't dictate package boundaries; this Agent Note does. +This is distinct from "who provides vs. needs a capability at runtime", which Cordis already answers with services + `inject` (a provider registers `ctx.shell`; a consumer declares `inject: ['bash']` and its fiber pends until the service exists). That mechanism is necessary but doesn't dictate package boundaries; this Agent Note does. ## Decision A swappable capability has **three roles**: -1. **Service Definition** — the Cordis `Service` and vocabulary types owning `ctx.` and depending only on the vocabulary the contract needs (e.g. `dsh-bash`: `BashExecutor`, `BashRunResult`, `BashProcess`). A definition may be an abstract class or a concrete registry service; it is never a TypeScript `interface`. +1. **Service Definition** — the Cordis `Service` and vocabulary types owning `ctx.` and depending only on the vocabulary the contract needs (e.g. `dsh-shell`: `ShellExecutor`, `ShellRunResult`, `ShellProcess`). A definition may be an abstract class or a concrete registry service; it is never a TypeScript `interface`. 2. **Service provider** — a plugin that supplies or registers an implementation (e.g. `dsh-bash-local`: subprocesses, process-group kills, spill-file truncation). Sandboxed and remote providers are sibling packages implementing or registering against the same Service Definition. -3. **Consumer** — what the model and plugins program against (e.g. `dsh-tool-bash`: the `bash` schema, with background handles registered into the generic task runtime). Consumers inject the service key and never import provider-specific types. +3. **Consumer** — what the model and plugins program against (e.g. `dsh-tool-bash`: the `bash` schema, with background handles registered into the generic job runtime). Consumers inject the service key and never import provider-specific types. Service providers and Consumers then evolve independently: a sandboxed executor replaces `dsh-bash-local` without touching a tool schema. @@ -24,7 +24,7 @@ Roles normally use separate packages when they evolve independently, but the spl ## Terminology: "seam" names the trio, not the interface -A **seam** is the whole capability — the three roles together: a **Service Definition** (the Cordis `Service` that owns `ctx.` and the vocabulary), one or more **Service providers**, and one or more **Consumers**. `packages/bash` is the canonical example — `dsh-bash` / `dsh-bash-local`+`dsh-bash-sandbox` / `dsh-tool-bash`. A package may own multiple roles, but one role alone is not the seam. The term "seam" is reserved for this complete capability; name a constituent by its role, class, service, contract, or extension point. The [glossary](../../../../docs/glossary.md#capability-seam) is the canonical entry. +A **seam** is the whole capability — the three roles together: a **Service Definition** (the Cordis `Service` that owns `ctx.` and the vocabulary), one or more **Service providers**, and one or more **Consumers**. `packages/shell` is the canonical example — `dsh-shell` / `dsh-bash-local`+`dsh-bash-sandbox` / `dsh-tool-bash`. A package may own multiple roles, but one role alone is not the seam. The term "seam" is reserved for this complete capability; name a constituent by its role, class, service, contract, or extension point. The [glossary](../../../../docs/glossary.md#capability-seam) is the canonical entry. ## Alternatives considered diff --git a/.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md b/.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md index 79befde573..bf6571dfa5 100644 --- a/.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md +++ b/.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md @@ -8,13 +8,13 @@ Status: implemented harness 具有可替换的能力:当前是 bash 执行,未来会有沙箱化/远程执行器和替代模型提供方。一项能力涉及三个关注点,它们以不同速率、因不同原因变化:*约定*(这项能力是什么)、*实现*(它如何运行)、*消费方 API*(模型和其他插件面向什么编程)。将三者捆绑在一个包中会耦合这些变化速率——把本地执行器换成沙箱化执行器时,模型看到的工具 schema 也会被搅动,尽管面向模型的约定从未改变。 -这与「谁在运行时提供、谁需要一项能力」是不同的问题,后者 Cordis 已通过服务 + `inject` 解决(提供方注册 `ctx.bash`;消费方声明 `inject: ['bash']`,其 fiber 挂起直到服务存在)。该机制是必要的,但不决定包的边界;本 Agent Note 决定的是包的边界。 +这与「谁在运行时提供、谁需要一项能力」是不同的问题,后者 Cordis 已通过服务 + `inject` 解决(提供方注册 `ctx.shell`;消费方声明 `inject: ['bash']`,其 fiber 挂起直到服务存在)。该机制是必要的,但不决定包的边界;本 Agent Note 决定的是包的边界。 ## 决策 一项可替换的能力包含**三个角色**: -1. **Service Definition**——拥有 `ctx.` 的 Cordis `Service` 和词汇类型,仅依赖约定所需的词汇(例如 `dsh-bash`:`BashExecutor`、`BashRunResult`、`BashProcess`)。Service Definition 可以是抽象类,也可以是具体的注册表服务;绝不是 TypeScript `interface`。 +1. **Service Definition**——拥有 `ctx.` 的 Cordis `Service` 和词汇类型,仅依赖约定所需的词汇(例如 `dsh-shell`:`ShellExecutor`、`ShellRunResult`、`ShellProcess`)。Service Definition 可以是抽象类,也可以是具体的注册表服务;绝不是 TypeScript `interface`。 2. **Service provider**——提供或注册实现的插件(例如 `dsh-bash-local`:子进程、进程组 kill、spill 文件截断)。沙箱化和远程 Service provider 是依据同一 Service Definition 实现或注册的兄弟包。 3. **Consumer**——模型和插件编程所面向的内容(例如 `dsh-tool-bash`:`bash` schema,后台句柄注册到通用任务运行时)。Consumer 注入服务键,从不导入 Service provider 特有的类型。 @@ -24,7 +24,7 @@ Service provider 与 Consumer 由此独立演进:沙箱化执行器替换 `dsh ## 术语:seam 指三者组合,而非接口 -一个 **seam** 是完整的能力——三个角色合在一起:**Service Definition**(拥有 `ctx.` 和词汇的 Cordis `Service`)、一个或多个 **Service provider**,以及一个或多个 **Consumer**。`packages/bash` 是规范范例——`dsh-bash` / `dsh-bash-local`+`dsh-bash-sandbox` / `dsh-tool-bash`。一个包可以承担多个角色,但单个角色本身不是 seam。「seam」一词严格保留给这种完整能力;命名其中一个组成部分时,应使用其角色、类、服务、约定或扩展点。[术语表](../../../../docs/glossary.md#capability-seam)是规范条目。 +一个 **seam** 是完整的能力——三个角色合在一起:**Service Definition**(拥有 `ctx.` 和词汇的 Cordis `Service`)、一个或多个 **Service provider**,以及一个或多个 **Consumer**。`packages/shell` 是规范范例——`dsh-shell` / `dsh-bash-local`+`dsh-bash-sandbox` / `dsh-tool-bash`。一个包可以承担多个角色,但单个角色本身不是 seam。「seam」一词严格保留给这种完整能力;命名其中一个组成部分时,应使用其角色、类、服务、约定或扩展点。[术语表](../../../../docs/glossary.md#capability-seam)是规范条目。 ## 曾考虑的替代方案 diff --git a/.agents/notes/implemented/architecture/2026-06-14-session-persistence.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-14-session-persistence.i18n.yaml index 880cda00e7..61f9754431 100644 --- a/.agents/notes/implemented/architecture/2026-06-14-session-persistence.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-14-session-persistence.i18n.yaml @@ -2,5 +2,5 @@ # 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 .agents/notes/implemented/architecture/2026-06-14-session-persistence.md -2026-06-14-session-persistence.md: 6961b8f3f4274587c2920fe2b2602aff5efe4afc -2026-06-14-session-persistence.zh.md: a99b236167d8f3229de083c917684d517b50ab9c +2026-06-14-session-persistence.md: 62228bd2f5b25b13880a563818d08f3a2d52d956 +2026-06-14-session-persistence.zh.md: b10ceebd95d4d05ae3f7ea620183ad8fffd074ee diff --git a/.agents/notes/implemented/architecture/2026-06-14-session-persistence.md b/.agents/notes/implemented/architecture/2026-06-14-session-persistence.md index 6961b8f3f4..62228bd2f5 100644 --- a/.agents/notes/implemented/architecture/2026-06-14-session-persistence.md +++ b/.agents/notes/implemented/architecture/2026-06-14-session-persistence.md @@ -12,7 +12,7 @@ The [event-sourced model](2026-06-11-event-sourced-sessions.md) makes the append ## Decision -Persistence is a **capability seam** with an abstract Service Definition ([capability seams](2026-06-13-capability-seams.md), the `dsh-bash` template), not loop or core logic: +Persistence is a **capability seam** with an abstract Service Definition ([capability seams](2026-06-13-capability-seams.md), the `dsh-shell` template), not loop or core logic: 1. **Interface** (`dsh-session-persistence`, `ctx.sessionPersistence`) — an abstract `SessionPersistence` service: `locate`/`create`/`append`/`prepare`/`load`/`inspect`/`readFrom`/`list`/`listSnapshots`. Its persisted unit IS the existing `SessionEvent` (`{ type, seq, time, data }`), reused verbatim — no conversion type. 2. **Implementation** (`dsh-session-persistence-jsonl`) — an append-only logical JSONL log per session: a `SessionHeader` line followed by storage records that losslessly represent the contiguous `SessionEvent` stream. Eligible `assistant/chunk` delta runs use packed rows by default; [checksummed Zstandard frames](2026-07-19-zstandard-jsonl-session-logs.md) are the default physical encoding, with raw lines configurable. diff --git a/.agents/notes/implemented/architecture/2026-06-14-session-persistence.zh.md b/.agents/notes/implemented/architecture/2026-06-14-session-persistence.zh.md index a99b236167..b10ceebd95 100644 --- a/.agents/notes/implemented/architecture/2026-06-14-session-persistence.zh.md +++ b/.agents/notes/implemented/architecture/2026-06-14-session-persistence.zh.md @@ -12,7 +12,7 @@ Status: implemented ## 决策 -持久化是一个具有抽象 Service Definition 的**能力 seam**([能力 seam](2026-06-13-capability-seams.md),`dsh-bash` 模板),而非循环或核心逻辑: +持久化是一个具有抽象 Service Definition 的**能力 seam**([能力 seam](2026-06-13-capability-seams.md),`dsh-shell` 模板),而非循环或核心逻辑: 1. **接口**(`dsh-session-persistence`,`ctx.sessionPersistence`):一个抽象的 `SessionPersistence` 服务,提供 `locate`/`create`/`append`/`prepare`/`load`/`inspect`/`readFrom`/`list`/`listSnapshots`。其持久化单元就是现有的 `SessionEvent`(`{ type, seq, time, data }`),原样复用,无转换类型。 2. **实现**(`dsh-session-persistence-jsonl`):每个会话一个仅追加的逻辑 JSONL 日志:先是一行 `SessionHeader`,随后是无损表示连续 `SessionEvent` 流的存储记录。符合条件的 `assistant/chunk` 增量连续段默认使用打包行;[带校验和的 Zstandard 帧](2026-07-19-zstandard-jsonl-session-logs.md)是默认物理编码,也可通过配置使用原始行。 diff --git a/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.i18n.yaml index 3ae4c57d3d..fc070d7c3a 100644 --- a/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.i18n.yaml @@ -2,5 +2,5 @@ # 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 .agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.md -2026-06-17-filesystem-capability-seam.md: 63628d592c17f000ae49f9558597bf8059f04942 -2026-06-17-filesystem-capability-seam.zh.md: d986869bf10f58c8e01873b1d77105accb7bea76 +2026-06-17-filesystem-capability-seam.md: 953ef0eaafe8f654bf55c3e5c4208560243c3d0b +2026-06-17-filesystem-capability-seam.zh.md: 1073226594acbe8c1c596bb4b2dcc959b20c0769 diff --git a/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.md b/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.md index 63628d592c..953ef0eaaf 100644 --- a/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.md +++ b/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.md @@ -6,7 +6,7 @@ English | [中文](2026-06-17-filesystem-capability-seam.zh.md) ## Problem -The harness has a concrete `bash` capability seam (`dsh-bash` / `dsh-bash-local` / `dsh-tool-bash`), but filesystem operations were about to land as model-facing tools without an equivalent seam. If `read`, `write`, and `edit` directly used `node:fs`, the model-facing tool package would own filesystem execution policy, local path resolution, atomic write behavior, text decoding, symlink behavior, and edit semantics all at once. +The harness has a concrete `bash` capability seam (`dsh-shell` / `dsh-bash-local` / `dsh-tool-bash`), but filesystem operations were about to land as model-facing tools without an equivalent seam. If `read`, `write`, and `edit` directly used `node:fs`, the model-facing tool package would own filesystem execution policy, local path resolution, atomic write behavior, text decoding, symlink behavior, and edit semantics all at once. That couples three concerns that change independently: @@ -28,7 +28,7 @@ Filesystem access is a first-class capability seam following [the capability-sea The Consumer package depends only on the Service Definition package, never on `dsh-fs-local`. A deployment that wants a different backend loads a different provider for `ctx.fs` without changing the tool schemas or model-facing prompt guidance. -The read-before-write/edit and observed-state policy is a fourth package, `@deepseek-ai/dsh-fs-policy` (`packages/fs/fs-policy`), contributed through the `fs/*` event gate rather than living on `ctx.fs`; a deployment loading `dsh-tool-fs` also loads `dsh-fs-policy` to get read-before-write/edit. This decision established the three-package boundary; the split of policy off the provider base class is decided by [the split-fs-seam Agent Note](../simplification/2026-06-26-fsspec-style-fs-seam.md), and its realization as an event-gate plugin (not a method service) by [the event-gate Agent Note](2026-06-26-file-context-as-event-gate.md). +The read-before-write/edit and observed-state policy is a fourth package, `@deepseek-ai/dsh-fs-observation-policy` (`packages/fs/fs-observation-policy`), contributed through the `fs/*` event gate rather than living on `ctx.fs`; a deployment loading `dsh-tool-fs` also loads `dsh-fs-observation-policy` to get read-before-write/edit. This decision established the three-package boundary; the split of policy off the provider base class is decided by [the split-fs-seam Agent Note](../simplification/2026-06-26-fsspec-style-fs-seam.md), and its realization as an event-gate plugin (not a method service) by [the event-gate Agent Note](2026-06-26-file-context-as-event-gate.md). The first backend is deliberately local-only: `dsh-fs-local` implements `ctx.fs` against the host filesystem. Future sibling backends can provide sandboxed, remote, virtual, or project-scoped filesystems behind the same interface. @@ -36,7 +36,7 @@ The first consumer is deliberately text-file-only: `dsh-tool-fs` exposes model-f Filesystem permissions and sandboxing are not implied by this split. The local backend resolves relative paths from its configured base directory, but containment policy is a separate decision: either a stricter `ctx.fs` implementation enforces it, or a permission/sandbox plugin wraps `tools/execute` and vetoes calls before they reach the consumer. -Read-before-write/edit and observed state belong to `dsh-fs-policy`, not `ctx.fs`. Through the `fs/*` event gate, the policy records versions per opaque actor and supplies optional mutation expectations; the provider enforces freshness atomically. `dsh-tool-fs` emits the events without depending on the policy. See the [split-seam](../simplification/2026-06-26-fsspec-style-fs-seam.md) and [event-gate](2026-06-26-file-context-as-event-gate.md) Agent Notes. +Read-before-write/edit and observed state belong to `dsh-fs-observation-policy`, not `ctx.fs`. Through the `fs/*` event gate, the policy records versions per opaque actor and supplies optional mutation expectations; the provider enforces freshness atomically. `dsh-tool-fs` emits the events without depending on the policy. See the [split-seam](../simplification/2026-06-26-fsspec-style-fs-seam.md) and [event-gate](2026-06-26-file-context-as-event-gate.md) Agent Notes. ## Package topology @@ -47,7 +47,7 @@ The filesystem seam uses the same dependency direction as the bash trio: consumer interface implementation ``` -`@deepseek-ai/dsh-fs` depends only on `cordis` plus the repo-wide `HarnessError` base from `@deepseek-ai/dsh-llm`. It declares the `ctx.fs` key, the abstract `FileSystem` service, the vocabulary types shared by backends and consumers, the filesystem error vocabulary, and the `fs/*` policy event vocabulary. It carries no observed-state store and no owner-derivation shape; the events pass an opaque `object` actor that the provider never reads, and the `dsh-fs-policy` plugin owns the owner-derivation shape and the observed-state store on top of those events. +`@deepseek-ai/dsh-fs` depends only on `cordis` plus the repo-wide `HarnessError` base from `@deepseek-ai/dsh-llm`. It declares the `ctx.fs` key, the abstract `FileSystem` service, the vocabulary types shared by backends and consumers, the filesystem error vocabulary, and the `fs/*` policy event vocabulary. It carries no observed-state store and no owner-derivation shape; the events pass an opaque `object` actor that the provider never reads, and the `dsh-fs-observation-policy` plugin owns the owner-derivation shape and the observed-state store on top of those events. `@deepseek-ai/dsh-fs-local` depends on `@deepseek-ai/dsh-fs` and `cordis`. It subclasses `FileSystem`, registers itself as `ctx.fs`, owns local-backend configuration such as the base directory, and contains all direct `node:fs` / `node:path` access. It holds no observed-state store — freshness is a version token the backend mints and the policy plugin records. @@ -68,13 +68,13 @@ The interface covers these semantic operations: - Create or replace a UTF-8 text file. - Edit an existing UTF-8 text file by literal replacement. -The provider contract also carries the freshness hooks that policy builds on — but the observed-state store and owner derivation live in the `dsh-fs-policy` plugin, not on `ctx.fs`: +The provider contract also carries the freshness hooks that policy builds on — but the observed-state store and owner derivation live in the `dsh-fs-observation-policy` plugin, not on `ctx.fs`: - The backend mints an opaque `version` token per target (in `stat` and in every read/mutation outcome). - `writeText`/`editText` take an OPTIONAL version expectation: omit it for an unconditional bare-provider mutation, or supply it to guard the mutation inside the backend's atomic critical section. -- The `dsh-fs-policy` plugin decides that expectation on `fs/write-intent`/`fs/edit-intent` and records observed versions on `fs/observed`, keyed by an owner it derives from the opaque event actor (normally `exec.agent.session`). +- The `dsh-fs-observation-policy` plugin decides that expectation on `fs/write-intent`/`fs/edit-intent` and records observed versions on `fs/observed`, keyed by an owner it derives from the opaque event actor (normally `exec.agent.session`). -Authorization is version freshness, not a full/partial view distinction: any read records the target's version, and a later write/edit is authorized as long as the file is still at that version — so a windowed read of lines 100-150 authorizes an edit of line 120. The observed-state store is a `WeakMap>` inside `dsh-fs-policy`; `dsh-fs` holds none of it and treats the actor as opaque. (This decision first modeled a `FileState` cache with `full`/`partial` views on `ctx.fs`; the split-fs-seam and event-gate notes replaced that with the freshness-based policy plugin described here.) +Authorization is version freshness, not a full/partial view distinction: any read records the target's version, and a later write/edit is authorized as long as the file is still at that version — so a windowed read of lines 100-150 authorizes an edit of line 120. The observed-state store is a `WeakMap>` inside `dsh-fs-observation-policy`; `dsh-fs` holds none of it and treats the actor as opaque. (This decision first modeled a `FileState` cache with `full`/`partial` views on `ctx.fs`; the split-fs-seam and event-gate notes replaced that with the freshness-based policy plugin described here.) Path resolution is explicit and allowed to be async. Local resolution may only normalize a path, but sandboxed/remote/project-scoped backends may need I/O to resolve a user-supplied path into a stable target identity. @@ -86,11 +86,11 @@ Resolved targets must expose at least three concepts: `targetKey` remains opaque even when another capability shares the provider's execution world. Such consumers ask the provider for `processPath(target)`, `fileUrl(target)`, or `contains(parent, child)`; the [portable execution-world decision](2026-07-28-portable-execution-world-consumers.md) owns why these facts sit on the filesystem seam. -Read and mutation results must include an opaque file `version`. The local backend derives its token from bigint stat metadata (`dev`, `ino`, `size`, `mtimeNs`, and `ctimeNs`) so same-size rewrites and inode replacement invalidate consumers reliably; a remote backend can use a revision id or hash-like token. The `dsh-fs-policy` plugin records versions for stale checks; consumers may display related metadata but must not interpret the version token. +Read and mutation results must include an opaque file `version`. The local backend derives its token from bigint stat metadata (`dev`, `ino`, `size`, `mtimeNs`, and `ctimeNs`) so same-size rewrites and inode replacement invalidate consumers reliably; a remote backend can use a revision id or hash-like token. The `dsh-fs-observation-policy` plugin records versions for stale checks; consumers may display related metadata but must not interpret the version token. -The provider hands back decoded text: `readText` returns a whole regular text file and `streamText` streams the same text semantics for large files or consumer-owned retention limits. Line windowing, byte ceilings, numbered-line rendering, and total-line accounting live in consumers such as `dsh-tool-fs` and `dsh-lsp-local`. The provider owns regular-file checks, UTF-8 decoding, and binary/NUL rejection; it does not know about line windows, protocol limits, or views. +The provider hands back decoded text: `readText` returns a whole regular text file and `streamText` streams the same text semantics for large files or consumer-owned retention limits. Line windowing, byte ceilings, numbered-line rendering, and total-line accounting live in consumers such as `dsh-tool-fs` and `dsh-lsp-stdio`. The provider owns regular-file checks, UTF-8 decoding, and binary/NUL rejection; it does not know about line windows, protocol limits, or views. -Observed-state recording is not on `ctx.fs`: after a successful read the executor emits `fs/observed`, and the `dsh-fs-policy` plugin records `{ version }` for the deriving owner. There is no `full`/`partial` view — a read at any window records the version, and freshness (not view completeness) authorizes a later write/edit. +Observed-state recording is not on `ctx.fs`: after a successful read the executor emits `fs/observed`, and the `dsh-fs-observation-policy` plugin records `{ version }` for the deriving owner. There is no `full`/`partial` view — a read at any window records the version, and freshness (not view completeness) authorizes a later write/edit. Full-file writes create or replace UTF-8 text files. Backends may create parent directories when that behavior is supported and documented. Existing non-regular targets are rejected. `writeText` takes an optional expectation: `createIfAbsent` creates a missing target and rejects an existing one with `FS_NOT_OBSERVED` (the path the policy uses for an unobserved owner); `replaceIfVersion` replaces only when the target exists at the observed version, else `FS_STALE_VERSION`; omitting the expectation is the unconditional bare-provider create-or-overwrite. The policy plugin chooses which expectation to supply from the owner's observed state. @@ -115,19 +115,19 @@ Each tool follows the same execution shape: 1. Validate and normalize model arguments. 2. Call the appropriate `ctx.fs` operation. 3. Format the result as `ContentBlock[]` for the model. -4. Let thrown backend/tool errors flow through `ToolRegistry.execute()`, which converts them into `isError` tool results. +4. Let thrown backend/tool errors flow through `ToolRuntime.execute()`, which converts them into `isError` tool results. -The package registers prompt guidance through `ctx.systemPrompt.section(...)` and registers schemas through `ctx.tools.register(...)`. Tool schemas still flow into the normal prompt assembly path via `SystemPrompt.assemble()` and `ToolRegistry.schemas()`; no agent-loop changes are required. +The package registers prompt guidance through `ctx.systemPrompt.section(...)` and registers schemas through `ctx.tools.register(...)`. Tool schemas still flow into the normal prompt assembly path via `SystemPrompt.assemble()` and `ToolRuntime.schemas()`; no agent-loop changes are required. The tool package keeps model-facing contracts stable when backends change: a local backend and a remote backend may resolve paths differently internally, but the `read` / `write` / `edit` schemas do not change solely because the backend changes. -The default deployment requires a prior `read` before updating an existing file with `write` or `edit`. `tool-fs` does not implement this by checking whether a tool named `read` ran: it dispatches the `fs/write-intent`/`fs/edit-intent` events (passing the execution context as the opaque actor), and the `dsh-fs-policy` plugin derives the owner, gates on prior observation, and supplies the version expectation. Any windowed read authorizes a later write/edit as long as the file is unchanged. Creating a new file with `write` does not require prior observation. +The default deployment requires a prior `read` before updating an existing file with `write` or `edit`. `tool-fs` does not implement this by checking whether a tool named `read` ran: it dispatches the `fs/write-intent`/`fs/edit-intent` events (passing the execution context as the opaque actor), and the `dsh-fs-observation-policy` plugin derives the owner, gates on prior observation, and supplies the version expectation. Any windowed read authorizes a later write/edit as long as the file is unchanged. Creating a new file with `write` does not require prior observation. The root plugin registers the full suite by composing the per-tool registration helpers. It injects `fs`, `tools`, and `systemPrompt`. ## Testing -Tests follow the package boundary, not only the user-visible tools: the service contract in `dsh-fs`; real filesystem behavior through the `ctx.fs` interface in `dsh-fs-local` (resolution, symlinks, streaming, binary/UTF-8 rejection, unconditional and version-guarded writes, literal-edit semantics, line-ending preservation, structured `FsError` codes); the consumer surface in `dsh-tool-fs` against the real local provider (mock only the model/clock, never the collaborator); and integration through `ctx.tools.execute()` with and without `dsh-fs-policy`, world-verified by reading files back from disk rather than trusting either the canonical value or rendered content. The observed-state/owner-derivation policy is tested in `dsh-fs-policy`, not here. +Tests follow the package boundary, not only the user-visible tools: the service contract in `dsh-fs`; real filesystem behavior through the `ctx.fs` interface in `dsh-fs-local` (resolution, symlinks, streaming, binary/UTF-8 rejection, unconditional and version-guarded writes, literal-edit semantics, line-ending preservation, structured `FsError` codes); the consumer surface in `dsh-tool-fs` against the real local provider (mock only the model/clock, never the collaborator); and integration through `ctx.tools.execute()` with and without `dsh-fs-observation-policy`, world-verified by reading files back from disk rather than trusting either the canonical value or rendered content. The observed-state/owner-derivation policy is tested in `dsh-fs-observation-policy`, not here. The defensive-pattern classes this repo has been bitten by are pinned directly: @@ -152,11 +152,11 @@ The defensive-pattern classes this repo has been bitten by are pinned directly: **Edit semantics are race-prone by nature.** Literal edit is a read-modify-write operation; the guard is the backend's atomic mutation critical section plus the optional version expectation, so concurrent edits settle deterministically — one wins, the other gets `FS_STALE_VERSION`. -**Observed state does not belong on `ctx.fs`.** Recording what an execution context has seen is workflow policy, not raw filesystem I/O. This decision first placed it inside the filesystem seam; the split-fs-seam note then established that a sandboxed/remote backend should not inherit model-facing observation policy, and moved it into the `dsh-fs-policy` plugin. The provider contract keeps only what write/edit safety genuinely needs at the storage layer — a backend-minted version token and an optional version-guarded mutation — while the policy plugin owns owner derivation, observed-state, and read-before-edit gating over the `fs/*` events. +**Observed state does not belong on `ctx.fs`.** Recording what an execution context has seen is workflow policy, not raw filesystem I/O. This decision first placed it inside the filesystem seam; the split-fs-seam note then established that a sandboxed/remote backend should not inherit model-facing observation policy, and moved it into the `dsh-fs-observation-policy` plugin. The provider contract keeps only what write/edit safety genuinely needs at the storage layer — a backend-minted version token and an optional version-guarded mutation — while the policy plugin owns owner derivation, observed-state, and read-before-edit gating over the `fs/*` events. **The `resolve`-then-operate shape costs an extra round-trip per call.** Each tool may resolve a path to an `FsTarget` and then issue the read/write/edit as a separate `ctx.fs` call. For the local backend this is negligible (resolution is in-memory path normalization), but a remote/sandboxed backend may turn each step into its own request, so a single `read` can become two network round-trips. Backends where the round-trip matters can cache or fold resolution internally while preserving the observable contract. -**Observed-state persistence is deferred.** Observed state lives in memory (the `WeakMap` inside `dsh-fs-policy`), so a resumed session conservatively requires files to be read again before write/edit until a future session-event or persistence mechanism makes observation replayable. +**Observed-state persistence is deferred.** Observed state lives in memory (the `WeakMap` inside `dsh-fs-observation-policy`), so a resumed session conservatively requires files to be read again before write/edit until a future session-event or persistence mechanism makes observation replayable. **Error codes become part of the seam.** `FsError` codes make stale-version and observation failures machine-routable through the existing structured error taxonomy. The cost is that `dsh-fs` imports the shared `HarnessError` base from `dsh-llm`; that dependency is intentional and stays limited to the error vocabulary. diff --git a/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.zh.md b/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.zh.md index d986869bf1..1073226594 100644 --- a/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.zh.md +++ b/.agents/notes/implemented/architecture/2026-06-17-filesystem-capability-seam.zh.md @@ -6,7 +6,7 @@ Status: implemented ## 问题 -harness 已有一个具体的 `bash` 能力 seam(`dsh-bash` / `dsh-bash-local` / `dsh-tool-bash`),但文件系统操作当时即将作为面向模型的工具落地,却没有等价的 seam。如果 `read`、`write` 和 `edit` 直接使用 `node:fs`,面向模型的工具包就会同时承担文件系统执行策略、本地路径解析、原子写入行为、文本解码、符号链接行为和编辑语义。 +harness 已有一个具体的 `bash` 能力 seam(`dsh-shell` / `dsh-bash-local` / `dsh-tool-bash`),但文件系统操作当时即将作为面向模型的工具落地,却没有等价的 seam。如果 `read`、`write` 和 `edit` 直接使用 `node:fs`,面向模型的工具包就会同时承担文件系统执行策略、本地路径解析、原子写入行为、文本解码、符号链接行为和编辑语义。 这把三个独立变化的关注点耦合在了一起: @@ -28,7 +28,7 @@ harness 已有一个具体的 `bash` 能力 seam(`dsh-bash` / `dsh-bash-local` Consumer 包仅依赖 Service Definition 包,从不依赖 `dsh-fs-local`。需要不同后端的部署只需为 `ctx.fs` 加载不同的提供方,无需改动工具 schema 或面向模型的提示词引导。 -读后写/编辑与观测状态策略是第四个包 `@deepseek-ai/dsh-fs-policy`(`packages/fs/fs-policy`),通过 `fs/*` 事件门控贡献,而非挂在 `ctx.fs` 上;加载 `dsh-tool-fs` 的部署同时加载 `dsh-fs-policy` 以获得读后写/编辑能力。本决策确立了由三个包构成的边界;策略从提供方基类拆出的决策由 [拆分文件系统 seam Agent Note](../simplification/2026-06-26-fsspec-style-fs-seam.md) 做出,其以事件门控插件(而非方法服务)实现的方式由 [事件门控 Agent Note](2026-06-26-file-context-as-event-gate.md) 做出。 +读后写/编辑与观测状态策略是第四个包 `@deepseek-ai/dsh-fs-observation-policy`(`packages/fs/fs-observation-policy`),通过 `fs/*` 事件门控贡献,而非挂在 `ctx.fs` 上;加载 `dsh-tool-fs` 的部署同时加载 `dsh-fs-observation-policy` 以获得读后写/编辑能力。本决策确立了由三个包构成的边界;策略从提供方基类拆出的决策由 [拆分文件系统 seam Agent Note](../simplification/2026-06-26-fsspec-style-fs-seam.md) 做出,其以事件门控插件(而非方法服务)实现的方式由 [事件门控 Agent Note](2026-06-26-file-context-as-event-gate.md) 做出。 第一个后端有意仅限本地:`dsh-fs-local` 基于宿主文件系统实现 `ctx.fs`。未来的兄弟后端可在同一接口之后提供沙箱、远程、虚拟或项目作用域的文件系统。 @@ -36,7 +36,7 @@ Consumer 包仅依赖 Service Definition 包,从不依赖 `dsh-fs-local`。需 文件系统权限和沙箱并非此拆分所隐含。本地后端从其配置的基目录解析相对路径,但路径包含约束策略是独立的决策:要么由更严格的 `ctx.fs` 实现强制执行,要么由权限/沙箱插件包装 `tools/execute` 并在调用到达消费方之前否决。 -读后写/编辑与观测状态属于 `dsh-fs-policy`,而非 `ctx.fs`。通过 `fs/*` 事件门控,策略按不透明 actor 记录版本,并提供可选的变更期望;提供方原子性地强制新鲜度。`dsh-tool-fs` 发出事件但不依赖策略。见[拆分文件系统 seam](../simplification/2026-06-26-fsspec-style-fs-seam.md)和[事件门控插件](2026-06-26-file-context-as-event-gate.md) Agent Note。 +读后写/编辑与观测状态属于 `dsh-fs-observation-policy`,而非 `ctx.fs`。通过 `fs/*` 事件门控,策略按不透明 actor 记录版本,并提供可选的变更期望;提供方原子性地强制新鲜度。`dsh-tool-fs` 发出事件但不依赖策略。见[拆分文件系统 seam](../simplification/2026-06-26-fsspec-style-fs-seam.md)和[事件门控插件](2026-06-26-file-context-as-event-gate.md) Agent Note。 ## 包拓扑 @@ -47,7 +47,7 @@ Consumer 包仅依赖 Service Definition 包,从不依赖 `dsh-fs-local`。需 consumer interface implementation ``` -`@deepseek-ai/dsh-fs` 仅依赖 `cordis` 加上来自 `@deepseek-ai/dsh-llm` 的仓库级 `HarnessError` 基类。它声明 `ctx.fs` 键、抽象 `FileSystem` 服务、后端和消费方共享的词汇类型、文件系统错误词汇,以及 `fs/*` 策略事件词汇。它不持有观测状态存储,也不持有 owner 推导形态;事件传递一个不透明的 `object` actor,提供方从不读取它,`dsh-fs-policy` 插件在这些事件之上拥有 owner 推导形态和观测状态存储。 +`@deepseek-ai/dsh-fs` 仅依赖 `cordis` 加上来自 `@deepseek-ai/dsh-llm` 的仓库级 `HarnessError` 基类。它声明 `ctx.fs` 键、抽象 `FileSystem` 服务、后端和消费方共享的词汇类型、文件系统错误词汇,以及 `fs/*` 策略事件词汇。它不持有观测状态存储,也不持有 owner 推导形态;事件传递一个不透明的 `object` actor,提供方从不读取它,`dsh-fs-observation-policy` 插件在这些事件之上拥有 owner 推导形态和观测状态存储。 `@deepseek-ai/dsh-fs-local` 依赖 `@deepseek-ai/dsh-fs` 和 `cordis`。它继承 `FileSystem`,将自身注册为 `ctx.fs`,拥有本地后端配置(如基目录),并包含所有直接的 `node:fs` / `node:path` 访问。它不持有观测状态存储——新鲜度是后端铸造、策略插件记录的版本令牌。 @@ -68,13 +68,13 @@ Consumer 包仅依赖 Service Definition 包,从不依赖 `dsh-fs-local`。需 - 创建或替换一个 UTF-8 文本文件。 - 通过字面替换编辑一个已有的 UTF-8 文本文件。 -提供方约定还携带策略所依赖的新鲜度钩子——但观测状态存储和 owner 推导位于 `dsh-fs-policy` 插件中,而非 `ctx.fs` 上: +提供方约定还携带策略所依赖的新鲜度钩子——但观测状态存储和 owner 推导位于 `dsh-fs-observation-policy` 插件中,而非 `ctx.fs` 上: - 后端为每个目标铸造一个不透明的 `version` 令牌(在 `stat` 以及每次读取/变更结果中)。 - `writeText`/`editText` 接受一个可选的版本期望:省略它表示无条件的裸提供方变更;提供它则在后端的原子临界区内守护变更。 -- `dsh-fs-policy` 插件在 `fs/write-intent`/`fs/edit-intent` 上决定该期望,并在 `fs/observed` 上记录观测版本,以它从不透明事件 actor 推导出的 owner 为键(通常是 `exec.agent.session`)。 +- `dsh-fs-observation-policy` 插件在 `fs/write-intent`/`fs/edit-intent` 上决定该期望,并在 `fs/observed` 上记录观测版本,以它从不透明事件 actor 推导出的 owner 为键(通常是 `exec.agent.session`)。 -授权基于版本新鲜度,而非完整/部分视图的区分:任何读取都会记录目标的版本,后续的写入/编辑只要文件仍处于该版本就被授权——因此对第 100-150 行的窗口化读取可以授权对第 120 行的编辑。观测状态存储是 `dsh-fs-policy` 内部的 `WeakMap>`;`dsh-fs` 不持有任何此类数据,并将 actor 视为不透明。(本决策最初建模了一个带 `full`/`partial` 视图的 `FileState` 缓存放在 `ctx.fs` 上;拆分文件系统 seam 与事件门控两份笔记将其替换为此处描述的基于新鲜度的策略插件。) +授权基于版本新鲜度,而非完整/部分视图的区分:任何读取都会记录目标的版本,后续的写入/编辑只要文件仍处于该版本就被授权——因此对第 100-150 行的窗口化读取可以授权对第 120 行的编辑。观测状态存储是 `dsh-fs-observation-policy` 内部的 `WeakMap>`;`dsh-fs` 不持有任何此类数据,并将 actor 视为不透明。(本决策最初建模了一个带 `full`/`partial` 视图的 `FileState` 缓存放在 `ctx.fs` 上;拆分文件系统 seam 与事件门控两份笔记将其替换为此处描述的基于新鲜度的策略插件。) 路径解析是显式的,允许异步。本地解析可能只做路径规范化,但沙箱/远程/项目作用域的后端可能需要 I/O 才能将用户提供的路径解析为稳定的目标标识。 @@ -86,11 +86,11 @@ Consumer 包仅依赖 Service Definition 包,从不依赖 `dsh-fs-local`。需 即使另一项能力共享提供方的执行环境,`targetKey` 仍保持不透明。这类消费方通过提供方的 `processPath(target)`、`fileUrl(target)` 或 `contains(parent, child)` 获取所需事实;[可移植执行环境决策](2026-07-28-portable-execution-world-consumers.md)说明这些事实为何属于文件系统 seam。 -读取和变更结果必须包含不透明的文件 `version`。本地后端从 bigint stat 元数据(`dev`、`ino`、`size`、`mtimeNs` 和 `ctimeNs`)派生令牌,因此同大小重写和 inode 替换都会可靠地使消费方失效;远程后端可以使用 revision id 或类似 hash 的令牌。`dsh-fs-policy` 插件记录版本用于陈旧检查;消费方可以展示相关元数据但禁止解释版本令牌。 +读取和变更结果必须包含不透明的文件 `version`。本地后端从 bigint stat 元数据(`dev`、`ino`、`size`、`mtimeNs` 和 `ctimeNs`)派生令牌,因此同大小重写和 inode 替换都会可靠地使消费方失效;远程后端可以使用 revision id 或类似 hash 的令牌。`dsh-fs-observation-policy` 插件记录版本用于陈旧检查;消费方可以展示相关元数据但禁止解释版本令牌。 -提供方返回已解码的文本:`readText` 返回整个普通文本文件,`streamText` 为大文件或消费方自有的保留上限流式传输相同的文本语义。行窗口化、字节上限、带行号渲染和总行数统计归 `dsh-tool-fs`、`dsh-lsp-local` 等消费方所有。提供方负责普通文件检查、UTF-8 解码和二进制/NUL 拒绝;它不知道行窗口、协议上限或视图。 +提供方返回已解码的文本:`readText` 返回整个普通文本文件,`streamText` 为大文件或消费方自有的保留上限流式传输相同的文本语义。行窗口化、字节上限、带行号渲染和总行数统计归 `dsh-tool-fs`、`dsh-lsp-stdio` 等消费方所有。提供方负责普通文件检查、UTF-8 解码和二进制/NUL 拒绝;它不知道行窗口、协议上限或视图。 -观测状态记录不在 `ctx.fs` 上:成功读取后,执行器发出 `fs/observed`,`dsh-fs-policy` 插件为推导出的 owner 记录 `{ version }`。没有 `full`/`partial` 视图——任何窗口的读取都记录版本,新鲜度(而非视图完整性)授权后续的写入/编辑。 +观测状态记录不在 `ctx.fs` 上:成功读取后,执行器发出 `fs/observed`,`dsh-fs-observation-policy` 插件为推导出的 owner 记录 `{ version }`。没有 `full`/`partial` 视图——任何窗口的读取都记录版本,新鲜度(而非视图完整性)授权后续的写入/编辑。 全文件写入创建或替换 UTF-8 文本文件。后端在支持且有文档说明时可以创建父目录。已有的非常规目标被拒绝。`writeText` 接受一个可选期望:`createIfAbsent` 创建缺失的目标并拒绝已存在的(报 `FS_NOT_OBSERVED`,这是策略为未观测 owner 使用的路径);`replaceIfVersion` 仅在目标处于观测版本时替换,否则报 `FS_STALE_VERSION`;省略期望则为无条件的裸提供方创建或覆盖。策略插件根据 owner 的观测状态选择提供哪个期望。 @@ -115,19 +115,19 @@ Consumer 包仅依赖 Service Definition 包,从不依赖 `dsh-fs-local`。需 1. 校验并规范化模型参数。 2. 调用相应的 `ctx.fs` 操作。 3. 将结果格式化为面向模型的 `ContentBlock[]`。 -4. 让抛出的后端/工具错误流经 `ToolRegistry.execute()`,由其转换为 `isError` 工具结果。 +4. 让抛出的后端/工具错误流经 `ToolRuntime.execute()`,由其转换为 `isError` 工具结果。 -该包通过 `ctx.systemPrompt.section(...)` 注册提示词引导,通过 `ctx.tools.register(...)` 注册 schema。工具 schema 仍通过 `SystemPrompt.assemble()` 和 `ToolRegistry.schemas()` 流入正常的提示词组装路径;无需改动 agent loop(智能体循环)。 +该包通过 `ctx.systemPrompt.section(...)` 注册提示词引导,通过 `ctx.tools.register(...)` 注册 schema。工具 schema 仍通过 `SystemPrompt.assemble()` 和 `ToolRuntime.schemas()` 流入正常的提示词组装路径;无需改动 agent loop(智能体循环)。 工具包在后端变化时保持面向模型的约定稳定:本地后端和远程后端内部可能以不同方式解析路径,但 `read` / `write` / `edit` schema 不会仅因后端变化而改变。 -默认部署要求在用 `write` 或 `edit` 更新已有文件之前先 `read`。`tool-fs` 不通过检查是否运行过名为 `read` 的工具来实现这一点:它分发 `fs/write-intent`/`fs/edit-intent` 事件(将执行上下文作为不透明 actor 传递),`dsh-fs-policy` 插件推导 owner、对先前观测进行门控并提供版本期望。任何窗口化读取都能授权后续的写入/编辑,只要文件未变。用 `write` 创建新文件不要求先前观测。 +默认部署要求在用 `write` 或 `edit` 更新已有文件之前先 `read`。`tool-fs` 不通过检查是否运行过名为 `read` 的工具来实现这一点:它分发 `fs/write-intent`/`fs/edit-intent` 事件(将执行上下文作为不透明 actor 传递),`dsh-fs-observation-policy` 插件推导 owner、对先前观测进行门控并提供版本期望。任何窗口化读取都能授权后续的写入/编辑,只要文件未变。用 `write` 创建新文件不要求先前观测。 根插件通过组合各工具的注册辅助函数来注册完整套件。它注入 `fs`、`tools` 和 `systemPrompt`。 ## 测试 -测试遵循包边界,而不仅是用户可见的工具:`dsh-fs` 中的服务约定;`dsh-fs-local` 中通过 `ctx.fs` 接口测试的真实文件系统行为(解析、符号链接、流式传输、二进制/UTF-8 拒绝、无条件和版本守护的写入、字面编辑语义、行尾保留、结构化 `FsError` 错误码);`dsh-tool-fs` 中基于真实本地提供方的消费方接口(只 mock 模型/时钟,从不 mock 协作者);以及通过 `ctx.tools.execute()` 在有和没有 `dsh-fs-policy` 的情况下进行集成测试,通过从磁盘回读文件来验证世界状态,既不信任规范值,也不信任渲染内容。观测状态/owner 推导策略在 `dsh-fs-policy` 中测试,不在此处。 +测试遵循包边界,而不仅是用户可见的工具:`dsh-fs` 中的服务约定;`dsh-fs-local` 中通过 `ctx.fs` 接口测试的真实文件系统行为(解析、符号链接、流式传输、二进制/UTF-8 拒绝、无条件和版本守护的写入、字面编辑语义、行尾保留、结构化 `FsError` 错误码);`dsh-tool-fs` 中基于真实本地提供方的消费方接口(只 mock 模型/时钟,从不 mock 协作者);以及通过 `ctx.tools.execute()` 在有和没有 `dsh-fs-observation-policy` 的情况下进行集成测试,通过从磁盘回读文件来验证世界状态,既不信任规范值,也不信任渲染内容。观测状态/owner 推导策略在 `dsh-fs-observation-policy` 中测试,不在此处。 本仓库曾踩过的防御性模式类别被直接固定: @@ -152,11 +152,11 @@ Consumer 包仅依赖 Service Definition 包,从不依赖 `dsh-fs-local`。需 **编辑语义天然易受竞争影响。** 字面编辑是读-改-写操作;守护手段是后端的原子变更临界区加上可选的版本期望,因此并发编辑确定性地收敛——一个赢,另一个得到 `FS_STALE_VERSION`。 -**观测状态不属于 `ctx.fs`。** 记录执行上下文看到了什么是工作流策略,而非原始文件系统 I/O。本决策最初将其放在文件系统 seam 内部;拆分文件系统 seam 笔记随后确立了沙箱/远程后端不应继承面向模型的观测策略,并将其移入 `dsh-fs-policy` 插件。提供方约定只保留写入/编辑安全在存储层真正需要的东西——后端铸造的版本令牌和可选的版本守护变更——而策略插件拥有 owner 推导、观测状态和基于 `fs/*` 事件的读后编辑门控。 +**观测状态不属于 `ctx.fs`。** 记录执行上下文看到了什么是工作流策略,而非原始文件系统 I/O。本决策最初将其放在文件系统 seam 内部;拆分文件系统 seam 笔记随后确立了沙箱/远程后端不应继承面向模型的观测策略,并将其移入 `dsh-fs-observation-policy` 插件。提供方约定只保留写入/编辑安全在存储层真正需要的东西——后端铸造的版本令牌和可选的版本守护变更——而策略插件拥有 owner 推导、观测状态和基于 `fs/*` 事件的读后编辑门控。 **`resolve` 然后操作的形态每次调用多一次往返。** 每个工具可能先将路径解析为 `FsTarget`,再以单独的 `ctx.fs` 调用发起读取/写入/编辑。对本地后端来说这可以忽略(解析是内存中的路径规范化),但远程/沙箱后端可能将每步变成独立请求,使单次 `read` 变为两次网络往返。往返开销重要的后端可以在内部缓存或折叠解析,同时保持可观测约定不变。 -**观测状态持久化被推迟。** 观测状态存在于内存中(`dsh-fs-policy` 内部的 `WeakMap`),因此恢复的会话保守地要求文件在写入/编辑前重新读取,直到未来的会话事件或持久化机制使观测可回放。 +**观测状态持久化被推迟。** 观测状态存在于内存中(`dsh-fs-observation-policy` 内部的 `WeakMap`),因此恢复的会话保守地要求文件在写入/编辑前重新读取,直到未来的会话事件或持久化机制使观测可回放。 **错误码成为 seam 的一部分。** `FsError` 错误码使陈旧版本和观测失败可通过既有的结构化错误分类体系进行机器路由。代价是 `dsh-fs` 从 `dsh-llm` 导入共享的 `HarnessError` 基类;该依赖是有意为之且限于错误词汇。 diff --git a/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.i18n.yaml index ac99292150..d3c3a774bd 100644 --- a/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.i18n.yaml @@ -2,5 +2,5 @@ # 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 .agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.md -2026-06-18-agent-lifecycle-and-ownership-contracts.md: c3522d18dad2703664f12364e4d70cc057a3a945 -2026-06-18-agent-lifecycle-and-ownership-contracts.zh.md: 16781c8a5d1a1c67d1fe9296b0f34f2a00b11caf +2026-06-18-agent-lifecycle-and-ownership-contracts.md: f0f9f90b15dee9155cfb1e8c772503642ff34be3 +2026-06-18-agent-lifecycle-and-ownership-contracts.zh.md: a5f6ca10dbe7c71281cccdaf83fff95139ad2d79 diff --git a/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.md b/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.md index c3522d18da..f0f9f90b15 100644 --- a/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.md +++ b/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.md @@ -6,7 +6,7 @@ English | [中文](2026-06-18-agent-lifecycle-and-ownership-contracts.zh.md) ## Problem -Several ACP and tool-bash limitations were symptoms of the same missing ownership contract: plugins could create or resume agents through `ctx.agents`, but they could not own and dispose one agent independently, and long-running bash tasks carried no stable owner in the executor itself. ACP aborted and awaited agents on disconnect but could not unregister just that session's agent; `session/cancel` could not cancel queued-but-not-yet-started work; and `tool-bash` kept task ownership in a plugin-local `Map`, so an HMR reload could make an old task look unowned. +Several ACP and tool-bash limitations were symptoms of the same missing ownership contract: plugins could create or resume agents through `ctx.agents`, but they could not own and dispose one agent independently, and long-running bash tasks carried no stable owner in the executor itself. ACP aborted and awaited agents on disconnect but could not unregister just that session's agent; `session/cancel` could not cancel queued-but-not-yet-started work; and `tool-bash` kept job ownership in a plugin-local `Map`, so an HMR reload could make an old task look unowned. ## Decision @@ -24,7 +24,7 @@ A new `cancel()` verb on the `Agent` interface — the single public stop primit ### 3. Bash owner token in the Service Definition -Background-task ownership moved from a `tool-bash` plugin-local `Map` into the executor. `BashExecRequest` gains an optional `owner?: string`; the resolved `BashExecSpec` carries it as required-but-nullable `owner: string | undefined` (a forgotten owner is a visible `undefined`, never a silently-absent property). The executor stores the token on its task and exposes it via a new `BashExecutor.ownerOf(id): string | undefined` method (NOT on the public `BashTask` — one read path, no redundant API). `tool-bash` deletes its `Map` entirely: it stamps `exec.agent?.id` (the shared registry/session id) as the owner at `start`, and `bash_output`/`bash_kill` compare `ctx.bash.ownerOf(id)` to the caller's token with `!== undefined` semantics (an empty-string token is still a real owner). The completion notice finds the live agent by scanning `ctx.get('agents')?.list()` for `agent.id === ownerToken` (read via `ctx.get` — `onTaskDone` runs on the bash fiber, a foreign fiber, where the `ctx.agents` proxy would throw). Because ownership now lives on the task in the executor (disposed with the `dsh-bash` fiber), it SURVIVES a `tool-bash` HMR reload — closing the old `XXX(tool-bash-owner-hmr)` gap. (The `onTaskDone` listener is still effect-scoped to `tool-bash`'s `apply`, so a completion landing during the reload gap still drops its one notice — the pre-existing reload-gap drop — but the ownership fence itself is HMR-proof.) +Background-job ownership moved from a `tool-bash` plugin-local `Map` into the executor. `ShellExecRequest` gains an optional `owner?: string`; the resolved `ShellExecSpec` carries it as required-but-nullable `owner: string | undefined` (a forgotten owner is a visible `undefined`, never a silently-absent property). The executor stores the token on its task and exposes it via a new `ShellExecutor.ownerOf(id): string | undefined` method (NOT on the public `BashTask` — one read path, no redundant API). `tool-bash` deletes its `Map` entirely: it stamps `exec.agent?.id` (the shared registry/session id) as the owner at `start`, and `bash_output`/`bash_kill` compare `ctx.shell.ownerOf(id)` to the caller's token with `!== undefined` semantics (an empty-string token is still a real owner). The completion notice finds the live agent by scanning `ctx.get('agents')?.list()` for `agent.id === ownerToken` (read via `ctx.get` — `onJobDone` runs on the bash fiber, a foreign fiber, where the `ctx.agents` proxy would throw). Because ownership now lives on the task in the executor (disposed with the `dsh-shell` fiber), it SURVIVES a `tool-bash` HMR reload — closing the old `XXX(tool-bash-owner-hmr)` gap. (The `onJobDone` listener is still effect-scoped to `tool-bash`'s `apply`, so a completion landing during the reload gap still drops its one notice — the pre-existing reload-gap drop — but the ownership fence itself is HMR-proof.) ## Verification @@ -32,7 +32,7 @@ These invariants hold and are pinned by tests: - ACP disconnect or plugin teardown leaves no registered agent and no session-store entry for any bridge-owned session, including a create racing connection closure. - `session/cancel` before a queued prompt starts prevents that prompt from running; a later accepted prompt remains an independent queued turn. -- A `tool-bash` HMR reload does NOT make an existing background task readable or killable by a different session (ownership survives on the executor). +- A `tool-bash` HMR reload does NOT make an existing background job readable or killable by a different session (ownership survives on the executor). - Existing non-ACP demos still work without managing handles explicitly; config-created agents remain owned by the `AgentLoop` plugin fiber. ## Session owner tokens are unique among live agents @@ -41,7 +41,7 @@ The bash owner-token comparison relies on the shared `Agent.id`/`SessionId` bein ## Alternatives considered -- **A public `BashTask.owner` field** instead of the `BashExecutor.ownerOf(id)` Service Definition method — rejected: one read path, no redundant API. +- **A public `BashTask.owner` field** instead of the `ShellExecutor.ownerOf(id)` Service Definition method — rejected: one read path, no redundant API. - **Sibling cordis effects for the agent's session lifecycle** — rejected: a fiber unload disposes sibling effects concurrently (`Promise.all`), racing removal of the store-owned append publication hooks against the loop's closing `session/flush`; the single composite effect's ordered LIFO chain is what captures the closing `turn/end` on both disposal paths. - **A separate step-only `abort()` beside `cancel()`** — shipped originally, then removed as unused; `cancel()` is the single public stop primitive ([the public-stop-API Agent Note](../simplification/2026-06-20-public-agent-stop-api.md)). diff --git a/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.zh.md b/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.zh.md index 16781c8a5d..a5f6ca10db 100644 --- a/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.zh.md +++ b/.agents/notes/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-contracts.zh.md @@ -24,7 +24,7 @@ ACP(Agent Client Protocol)与 tool-bash 的若干限制是同一个所有权 ### 3. Service Definition 中的 Bash 所有者令牌 -后台任务所有权从 `tool-bash` 插件本地的 `Map` 移入执行器。`BashExecRequest` 新增可选的 `owner?: string`;解析后的 `BashExecSpec` 将其作为必需但可空的 `owner: string | undefined` 携带(被遗忘的 owner 是可见的 `undefined`,而非静默缺失的属性)。执行器把 token 存在任务上,并通过新的 `BashExecutor.ownerOf(id): string | undefined` 方法暴露它(不放在公开的 `BashTask` 上——只有一条读取路径,没有冗余 API)。`tool-bash` 完全删除其 `Map`:它在 `start` 时将 `exec.agent?.id`(共享的注册表/会话 id)盖章为 owner,`bash_output`/`bash_kill` 则以 `!== undefined` 语义把 `ctx.bash.ownerOf(id)` 与调用方 token 比较(空字符串 token 仍是真实 owner)。完成通知通过扫描 `ctx.get('agents')?.list()` 查找 `agent.id === ownerToken` 的存活 agent(经 `ctx.get` 读取——`onTaskDone` 运行在 bash fiber 这一外部 fiber 上,直接使用 `ctx.agents` proxy 会抛异常)。由于所有权现在保存在执行器的任务上(随 `dsh-bash` fiber dispose),它能跨越 `tool-bash` HMR 重载,关闭旧的 `XXX(tool-bash-owner-hmr)` 缺口。(`onTaskDone` 监听器仍受 `tool-bash` 的 `apply` effect 约束,因此落在重载间隙的完成仍会丢失一条通知——既有的重载间隙丢失——但所有权隔离本身已经不受 HMR 影响。) +后台任务所有权从 `tool-bash` 插件本地的 `Map` 移入执行器。`ShellExecRequest` 新增可选的 `owner?: string`;解析后的 `ShellExecSpec` 将其作为必需但可空的 `owner: string | undefined` 携带(被遗忘的 owner 是可见的 `undefined`,而非静默缺失的属性)。执行器把 token 存在任务上,并通过新的 `ShellExecutor.ownerOf(id): string | undefined` 方法暴露它(不放在公开的 `BashTask` 上——只有一条读取路径,没有冗余 API)。`tool-bash` 完全删除其 `Map`:它在 `start` 时将 `exec.agent?.id`(共享的注册表/会话 id)盖章为 owner,`bash_output`/`bash_kill` 则以 `!== undefined` 语义把 `ctx.shell.ownerOf(id)` 与调用方 token 比较(空字符串 token 仍是真实 owner)。完成通知通过扫描 `ctx.get('agents')?.list()` 查找 `agent.id === ownerToken` 的存活 agent(经 `ctx.get` 读取——`onJobDone` 运行在 bash fiber 这一外部 fiber 上,直接使用 `ctx.agents` proxy 会抛异常)。由于所有权现在保存在执行器的任务上(随 `dsh-shell` fiber dispose),它能跨越 `tool-bash` HMR 重载,关闭旧的 `XXX(tool-bash-owner-hmr)` 缺口。(`onJobDone` 监听器仍受 `tool-bash` 的 `apply` effect 约束,因此落在重载间隙的完成仍会丢失一条通知——既有的重载间隙丢失——但所有权隔离本身已经不受 HMR 影响。) ## 验证 @@ -41,7 +41,7 @@ bash 所有者 token 比较依赖共享的 `Agent.id`/`SessionId` 在存活 agen ## 曾考虑的替代方案 -- **公开的 `BashTask.owner` 字段**而非 `BashExecutor.ownerOf(id)` Service Definition 方法:否决。一条读取路径即可,无需冗余 API。 +- **公开的 `BashTask.owner` 字段**而非 `ShellExecutor.ownerOf(id)` Service Definition 方法:否决。一条读取路径即可,无需冗余 API。 - **为 agent 的会话生命周期使用兄弟 Cordis effect**:否决。fiber 卸载时并发释放兄弟 effect(`Promise.all`),store 拥有的 append 发布钩子的移除与循环的关闭 `session/flush` 产生竞争;单一复合 effect 的有序 LIFO 链才能在两条释放路径上都捕获关闭的 `turn/end`。 - **在 `cancel()` 之外另设一个仅中止步骤的 `abort()`**:最初发布过,后因无人使用而移除;`cancel()` 是唯一的公开停止原语(见[公开停止接口 Agent Note](../simplification/2026-06-20-public-agent-stop-api.md))。 diff --git a/.agents/notes/implemented/architecture/2026-06-18-session-surface.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-18-session-surface.i18n.yaml index 8282967ba2..936e601b48 100644 --- a/.agents/notes/implemented/architecture/2026-06-18-session-surface.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-18-session-surface.i18n.yaml @@ -2,5 +2,5 @@ # 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 .agents/notes/implemented/architecture/2026-06-18-session-surface.md -2026-06-18-session-surface.md: fd48a4ee4e177b84a235b044b054e4ac266df8ba -2026-06-18-session-surface.zh.md: 496624016cd68e2e8b0fe65ed0246c5d469c4585 +2026-06-18-session-surface.md: 3682ae7b8b58b9e5d40695732c3a1531d0651d5e +2026-06-18-session-surface.zh.md: 8cba9645dc6d0c8a4d1ee096668fc0bc38aaa725 diff --git a/.agents/notes/implemented/architecture/2026-06-18-session-surface.md b/.agents/notes/implemented/architecture/2026-06-18-session-surface.md index fd48a4ee4e..3682ae7b8b 100644 --- a/.agents/notes/implemented/architecture/2026-06-18-session-surface.md +++ b/.agents/notes/implemented/architecture/2026-06-18-session-surface.md @@ -68,6 +68,6 @@ Every surface-eligible event must carry `surfaceOp` or it would disappear from d - **`packages/session/session-persistence-jsonl`**: No changes required. - **`packages/session/session-persistence`**: Abstract interface unchanged. -The surface is the foundation history manipulation ships on — dsh-compact's compaction rides it. A compaction or tool-result-prune plugin appends one of the existing message-producing event types (a `user/message` carrying the summary, say) with `surfaceOp: { op: 'replace', start, end }` and `sourceEventSeqs` covering the shadowed entries — the new event takes the range's place on the surface while the plugin's own trace events (e.g. `compaction/start`, `compaction/end`) stay off it. Replay preserves the decision deterministically. +The surface is the foundation history manipulation ships on — dsh-compaction's compaction rides it. A compaction or tool-result-pruner plugin appends one of the existing message-producing event types (a `user/message` carrying the summary, say) with `surfaceOp: { op: 'replace', start, end }` and `sourceEventSeqs` covering the shadowed entries — the new event takes the range's place on the surface while the plugin's own trace events (e.g. `compaction/start`, `compaction/end`) stay off it. Replay preserves the decision deterministically. A `tool/result` replacement may rewrite exactly one current `tool/result` and must preserve every data field except `content`. Session acceptance enforces this rule together with positional range and cited source-event validation, independent of optional diagnostic plugins. diff --git a/.agents/notes/implemented/architecture/2026-06-18-session-surface.zh.md b/.agents/notes/implemented/architecture/2026-06-18-session-surface.zh.md index 496624016c..8cba9645dc 100644 --- a/.agents/notes/implemented/architecture/2026-06-18-session-surface.zh.md +++ b/.agents/notes/implemented/architecture/2026-06-18-session-surface.zh.md @@ -68,6 +68,6 @@ export type SurfaceOp = - **`packages/session/session-persistence-jsonl`**:无需改动。 - **`packages/session/session-persistence`**:抽象接口不变。 -surface 是历史操纵赖以落地的基础——dsh-compact 的压缩就搭载于其上。压缩或 tool-result-prune 插件追加一个既有的消息产出事件类型(例如一条携带摘要的 `user/message`),附带 `surfaceOp: { op: 'replace', start, end }` 和覆盖被遮蔽条目的 `sourceEventSeqs`——新事件在 surface 上取代该范围的位置,而插件自身的 trace 事件(如 `compaction/start`、`compaction/end`)不进入 surface。回放以确定性方式保留该决策。 +surface 是历史操纵赖以落地的基础——dsh-compaction 的压缩就搭载于其上。压缩或 tool-result-pruner 插件追加一个既有的消息产出事件类型(例如一条携带摘要的 `user/message`),附带 `surfaceOp: { op: 'replace', start, end }` 和覆盖被遮蔽条目的 `sourceEventSeqs`——新事件在 surface 上取代该范围的位置,而插件自身的 trace 事件(如 `compaction/start`、`compaction/end`)不进入 surface。回放以确定性方式保留该决策。 一次 `tool/result` 替换只能改写当前的一个 `tool/result`,并且必须保留除 `content` 以外的每个数据字段。Session 接纳会与位置范围和引用的源事件校验一起强制这条规则,不依赖可选的诊断插件。 diff --git a/.agents/notes/implemented/architecture/2026-06-20-branded-ids.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-20-branded-ids.i18n.yaml index e6f65b6879..877a53e0ac 100644 --- a/.agents/notes/implemented/architecture/2026-06-20-branded-ids.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-20-branded-ids.i18n.yaml @@ -2,5 +2,5 @@ # 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 .agents/notes/implemented/architecture/2026-06-20-branded-ids.md -2026-06-20-branded-ids.md: ded48409bcb3deb19e35029fa795b5ea28c9f6d7 -2026-06-20-branded-ids.zh.md: 824d802b4aaec9f4a6ae530659387126a30fbc2d +2026-06-20-branded-ids.md: 6bf68c9b6b6dea8317992bcb6f694a8ee141f048 +2026-06-20-branded-ids.zh.md: 11a78df609888fdf917246940c12463373ff2de3 diff --git a/.agents/notes/implemented/architecture/2026-06-20-branded-ids.md b/.agents/notes/implemented/architecture/2026-06-20-branded-ids.md index ded48409bc..6bf68c9b6b 100644 --- a/.agents/notes/implemented/architecture/2026-06-20-branded-ids.md +++ b/.agents/notes/implemented/architecture/2026-06-20-branded-ids.md @@ -8,9 +8,9 @@ English | [中文](2026-06-20-branded-ids.zh.md) The harness brands `CallId` (`packages/llm/llm/src/brand.ts`) and the shared agent/session `SessionId` (`packages/core/session/src/types.ts`) using the `Branded = string & { readonly [BRAND]: B }` machinery (owned by the type-only `@deepseek-ai/dsh-brand` package at `packages/util/brand/` — see its [README](../../../../packages/util/brand/README.md)) and a zero-cost cast factory per type. `dsh-brand` also states the governing policy: *"Branding is for ids that cross package boundaries and could plausibly be confused; not every string needs a brand."* That policy is right; the problem is that it is only half-applied. Two gaps let a structurally-identical-but-semantically-wrong string slip through the type checker today. -**Gap 1 — unbranded cross-boundary IDs in the bash seam.** The background-task id is a plain `string`: `BashTask.id: string` (`packages/bash/bash/src/types.ts`), carried as `string` through the whole executor seam (`BashExecutor.get`/`ownerOf`/`readOutput`/`kill(id: string)` in `packages/bash/bash/src/index.ts`) and validated/passed as `string` by the model-facing tools (`validateTaskId`, `assertTaskAccess`, the `task_id` schema arg in `packages/bash/tool-bash/src/index.ts`). It is generated by a per-executor counter — `` `bash-${this.nextTaskId++}` `` in `packages/bash/bash-local/src/index.ts` — which gives it **exactly the same `name-N` shape as `SessionId`'s default** (`` `session-${++counter}` `` in `packages/core/session/src/index.ts`). A bash task id and a session id are trivially swappable at a call site and the compiler says nothing. It is a model-facing id (the model passes `task_id` back to `bash_output`/`bash_kill`), so a confusion here is reachable from untrusted input. +**Gap 1 — unbranded cross-boundary IDs in the bash seam.** The background-job id is a plain `string`: `BashTask.id: string` (`packages/shell/shell/src/types.ts`), carried as `string` through the whole executor seam (`ShellExecutor.get`/`ownerOf`/`readOutput`/`kill(id: string)` in `packages/shell/shell/src/index.ts`) and validated/passed as `string` by the model-facing tools (`validateJobId`, `assertTaskAccess`, the `job_id` schema arg in `packages/shell/tool-bash/src/index.ts`). It is generated by a per-executor counter — `` `bash-${this.nextTaskId++}` `` in `packages/shell/bash-local/src/index.ts` — which gives it **exactly the same `name-N` shape as `SessionId`'s default** (`` `session-${++counter}` `` in `packages/core/session/src/index.ts`). A bash job id and a session id are trivially swappable at a call site and the compiler says nothing. It is a model-facing id (the model passes `job_id` back to `bash_output`/`bash_kill`), so a confusion here is reachable from untrusted input. -The bash **owner token** is the related sub-case: `BashExecRequest.owner?: string` and `BashExecSpec.owner: string | undefined` (`packages/bash/bash/src/types.ts`) are documented as a deliberately *opaque* isolation key, but in every live caller the value IS the owning agent's shared `Agent.id`/`SessionId` (`callerToken = (exec) => exec.agent?.id` in `packages/bash/tool-bash/src/index.ts`) wearing a different seam-local name. It is compared for access control (`owner !== callerToken(exec)`), so a mismatched-but-well-typed string here is a cross-session isolation bug the type system currently cannot catch. This is the shared id alias covered by the [unified agent/session identity decision](../simplification/2026-06-20-unify-agent-and-session-id.md). +The bash **owner token** is the related sub-case: `ShellExecRequest.owner?: string` and `ShellExecSpec.owner: string | undefined` (`packages/shell/shell/src/types.ts`) are documented as a deliberately *opaque* isolation key, but in every live caller the value IS the owning agent's shared `Agent.id`/`SessionId` (`callerToken = (exec) => exec.agent?.id` in `packages/shell/tool-bash/src/index.ts`) wearing a different seam-local name. It is compared for access control (`owner !== callerToken(exec)`), so a mismatched-but-well-typed string here is a cross-session isolation bug the type system currently cannot catch. This is the shared id alias covered by the [unified agent/session identity decision](../simplification/2026-06-20-unify-agent-and-session-id.md). **Gap 2 — brand erosion at the boundaries of the *already-branded* IDs.** Even `CallId` and `SessionId` decay back to bare `string` at exactly the places confusion is most likely: registry/store key types and public method params. Representative sites include the session store, the agent registry (both keyed by the shared `SessionId`), tool-presentation call-id maps, ACP's session records, and the persistence coordinator. A brand that is dropped at a collection key buys nothing on lookups — the value of the existing brands is partly unrealized. @@ -18,9 +18,9 @@ The bash **owner token** is the related sub-case: `BashExecRequest.owner?: strin A type-only change. Brands are zero-cost casts; nothing about runtime behavior, serialization, comparison, or the wire format changes. The decision has three parts, all honoring the existing "not every string" policy. -- **Brand the bash task id.** Add `BashTaskId = Branded<'BashTaskId'>` plus its same-named factory in `packages/bash/bash/src/types.ts` (the package that *owns* the id), importing `Branded` from `@deepseek-ai/dsh-brand` exactly as `SessionId` does. The brand primitive lives in the dependency-free `dsh-brand` utility package precisely so `dsh-bash` can brand its ids by depending on it alone — it never pulls in `dsh-llm` (or `dsh-session`) just to reach `Branded`. Thread it through `BashTask.id`, the `BashExecutor` Service Definition methods (`get`/`ownerOf`/`readOutput`/`kill`), the generation site in `dsh-bash-local` (brand the counter output once, at creation), and the `dsh-tool-bash` validate/access surface (`validateTaskId` returns a `BashTaskId`; `task_id` is branded at the tool boundary where the model's string arrives). +- **Brand the bash job id.** Add `BashTaskId = Branded<'BashTaskId'>` plus its same-named factory in `packages/shell/shell/src/types.ts` (the package that *owns* the id), importing `Branded` from `@deepseek-ai/dsh-brand` exactly as `SessionId` does. The brand primitive lives in the dependency-free `dsh-brand` utility package precisely so `dsh-shell` can brand its ids by depending on it alone — it never pulls in `dsh-llm` (or `dsh-session`) just to reach `Branded`. Thread it through `BashTask.id`, the `ShellExecutor` Service Definition methods (`get`/`ownerOf`/`readOutput`/`kill`), the generation site in `dsh-bash-local` (brand the counter output once, at creation), and the `dsh-tool-bash` validate/access surface (`validateJobId` returns a `BashTaskId`; `job_id` is branded at the tool boundary where the model's string arrives). -- **Mint a distinct `OwnerToken` brand.** Add `OwnerToken = Branded<'OwnerToken'>` in `packages/bash/bash/src/types.ts`; type `BashExecRequest.owner` / `BashExecSpec.owner` / `BashExecutor.ownerOf` as `OwnerToken | undefined`. The `dsh-tool-bash` consumer casts the agent's shared `id` (`SessionId`) into an `OwnerToken` at the boundary — the one place the two vocabularies meet. The bash Service Definition never imports `dsh-session`. (Rationale in the next section.) +- **Mint a distinct `OwnerToken` brand.** Add `OwnerToken = Branded<'OwnerToken'>` in `packages/shell/shell/src/types.ts`; type `ShellExecRequest.owner` / `ShellExecSpec.owner` / `ShellExecutor.ownerOf` as `OwnerToken | undefined`. The `dsh-tool-bash` consumer casts the agent's shared `id` (`SessionId`) into an `OwnerToken` at the boundary — the one place the two vocabularies meet. The bash Service Definition never imports `dsh-session`. (Rationale in the next section.) - **Stop the brand erosion.** Propagate the existing brands to the `Map` key types and public method params listed under Gap 2 — `Map`, `Map`, `get(id: SessionId)`, `Map`, ACP's `SessionId` surface, and the coordinator's `Map`. This is the larger mechanical share of the change and the part that makes the *existing* brands actually load-bearing on lookups, not just on struct fields. @@ -46,21 +46,21 @@ export function OwnerToken(id: string): OwnerToken { ### Why not typing `owner` as `SessionId`? -The obvious shortcut is to type `owner` as `SessionId` directly — it always *is* one. We reject that. The bash executor seam is a capability seam (Service Definition `dsh-bash`, Service provider `dsh-bash-local`, Consumer `dsh-tool-bash`) and its owner token is *documented as deliberately opaque*: the executor "never interprets it (no access policy lives in the seam — that is the consumer's job)" (`packages/bash/bash/src/types.ts`). Typing the Service Definition's field as `SessionId` would import `dsh-session`'s vocabulary into a package that must not know what an owner token *means* — it would couple a generic execution backend to the session model and contradict the opaque-token design. A sandboxed or remote executor that replaces `dsh-bash-local` should not inherit a session dependency. The distinct `OwnerToken` brand keeps the seam decoupled: `dsh-bash` knows only "an owner is some opaque branded token," and the `dsh-tool-bash` consumer — which already decides the access policy — is the single boundary that casts its `SessionId` into an `OwnerToken`. The brand still delivers the safety win (you cannot pass a `BashTaskId` or a raw string where an owner is expected) without the coupling. +The obvious shortcut is to type `owner` as `SessionId` directly — it always *is* one. We reject that. The bash executor seam is a capability seam (Service Definition `dsh-shell`, Service provider `dsh-bash-local`, Consumer `dsh-tool-bash`) and its owner token is *documented as deliberately opaque*: the executor "never interprets it (no access policy lives in the seam — that is the consumer's job)" (`packages/shell/shell/src/types.ts`). Typing the Service Definition's field as `SessionId` would import `dsh-session`'s vocabulary into a package that must not know what an owner token *means* — it would couple a generic execution backend to the session model and contradict the opaque-token design. A sandboxed or remote executor that replaces `dsh-bash-local` should not inherit a session dependency. The distinct `OwnerToken` brand keeps the seam decoupled: `dsh-shell` knows only "an owner is some opaque branded token," and the `dsh-tool-bash` consumer — which already decides the access policy — is the single boundary that casts its `SessionId` into an `OwnerToken`. The brand still delivers the safety win (you cannot pass a `BashTaskId` or a raw string where an owner is expected) without the coupling. ## Out of scope / possible extensions Kept deliberately narrow per the "not every string needs a brand" policy. Each of these is a plausible future brand, deferred with a reason, not a commitment: -- **`ModelId`** (`GenerateOptions.model`, the `LlmService` adapter-registry key) — a real cross-package lookup key (config → agent → llm → adapter); a reasonable next brand, left out only to keep this decision's blast radius focused. -- **`ToolName`** (the `ToolRegistry` key) — author-defined, human-readable, and rarely confused with another id; the weakest candidate, likely not worth a brand. +- **`ModelId`** (`GenerateOptions.model`, the `LlmRuntime` adapter-registry key) — a real cross-package lookup key (config → agent → llm → adapter); a reasonable next brand, left out only to keep this decision's blast radius focused. +- **`ToolName`** (the `ToolRuntime` key) — author-defined, human-readable, and rarely confused with another id; the weakest candidate, likely not worth a brand. - **`ErrorCode`** (`HarnessError.code`) — a closed vocabulary (`ABORTED`, `NO_ADAPTER`, …), not a per-instance id; better served by a string-literal union than a brand, if anything. - **Numeric ordinals** — turn number, step number, and the event `seq` are `number`, not `string`, so `Branded` does not apply; a parallel `number & { readonly [BRAND]: B }` variant could brand them, but they are positional ordinals rarely passed across boundaries, so the payoff is low. - **Validated construction** — the brand factories are pure casts with no runtime check, and every boundary (ACP `sessionId`, provider-issued `call.id`, the empty-string fallback in `dsh-llm-deepseek`) trusts the raw string today. A `SessionId.parse()` / `isValid()` companion that throws on malformed input at boundaries is a genuine gap, but it is a *runtime-behavior* change with its own design (what is "malformed"? what happens on failure?) and belongs in its own decision, not bundled into this type-only change. ## Verification -The landed invariants: `BashTaskId` and `OwnerToken` are defined in `dsh-bash` and threaded end-to-end (Service Definition, the `dsh-bash-local` generation site, the `dsh-tool-bash` model-facing tool) with no `dsh-bash` dependency on `dsh-session`; no collection keyed by an in-scope branded id (`CallId`/`SessionId`/`BashTaskId`) is keyed by bare `string`; public method params and exported signatures keep the brand; and brands are constructed via the cast factory at each boundary where a raw string enters (provider call id, ACP session id, model-supplied `task_id`), never as scattered `as` casts. +The landed invariants: `BashTaskId` and `OwnerToken` are defined in `dsh-shell` and threaded end-to-end (Service Definition, the `dsh-bash-local` generation site, the `dsh-tool-bash` model-facing tool) with no `dsh-shell` dependency on `dsh-session`; no collection keyed by an in-scope branded id (`CallId`/`SessionId`/`BashTaskId`) is keyed by bare `string`; public method params and exported signatures keep the brand; and brands are constructed via the cast factory at each boundary where a raw string enters (provider call id, ACP session id, model-supplied `job_id`), never as scattered `as` casts. ## Consequences diff --git a/.agents/notes/implemented/architecture/2026-06-20-branded-ids.zh.md b/.agents/notes/implemented/architecture/2026-06-20-branded-ids.zh.md index 824d802b4a..11a78df609 100644 --- a/.agents/notes/implemented/architecture/2026-06-20-branded-ids.zh.md +++ b/.agents/notes/implemented/architecture/2026-06-20-branded-ids.zh.md @@ -8,9 +8,9 @@ Status: implemented harness 使用 `Branded = string & { readonly [BRAND]: B }` 机制,为 `CallId`(`packages/llm/llm/src/brand.ts`)和 agent(智能体)/会话共享的 `SessionId`(`packages/core/session/src/types.ts`)做 brand 处理;该机制由纯类型包 `@deepseek-ai/dsh-brand` 拥有,位于 `packages/util/brand/`,见其 [README](../../../../packages/util/brand/README.md),并为每个类型提供零开销的 cast 工厂。`dsh-brand` 还声明了治理策略:*「Branding 用于跨包边界且可能被混淆的 id;不是每个 string 都需要 brand。」* 这条策略是正确的;问题在于它只落实了一半。两处缺口使得结构相同但语义错误的 string 今天仍能通过类型检查器。 -**缺口 1:bash seam 中未 brand 的跨边界 ID。** 后台 task id 是普通 `string`:`BashTask.id: string`(`packages/bash/bash/src/types.ts`),作为 `string` 贯穿整个执行器 seam(`packages/bash/bash/src/index.ts` 中的 `BashExecutor.get`/`ownerOf`/`readOutput`/`kill(id: string)`),再由面向模型的工具以 `string` 校验并传递(`validateTaskId`、`assertTaskAccess`、`packages/bash/tool-bash/src/index.ts` 中 `task_id` 的 schema 参数)。它由每执行器计数器生成——`packages/bash/bash-local/src/index.ts` 中的 `` `bash-${this.nextTaskId++}` ``——其形状与 `SessionId` 的默认值**完全相同,都是 `name-N`**(`packages/core/session/src/index.ts` 中的 `` `session-${++counter}` ``)。bash task id 和会话 id 在调用点轻易就能互换,而编译器毫无反应。它是面向模型的 id(模型会把 `task_id` 传回 `bash_output`/`bash_kill`),所以该混淆可由不受信任的输入触达。 +**缺口 1:bash seam 中未 brand 的跨边界 ID。** 后台 job id 是普通 `string`:`BashTask.id: string`(`packages/shell/shell/src/types.ts`),作为 `string` 贯穿整个执行器 seam(`packages/shell/shell/src/index.ts` 中的 `ShellExecutor.get`/`ownerOf`/`readOutput`/`kill(id: string)`),再由面向模型的工具以 `string` 校验并传递(`validateJobId`、`assertTaskAccess`、`packages/shell/tool-bash/src/index.ts` 中 `job_id` 的 schema 参数)。它由每执行器计数器生成——`packages/shell/bash-local/src/index.ts` 中的 `` `bash-${this.nextTaskId++}` ``——其形状与 `SessionId` 的默认值**完全相同,都是 `name-N`**(`packages/core/session/src/index.ts` 中的 `` `session-${++counter}` ``)。bash job id 和会话 id 在调用点轻易就能互换,而编译器毫无反应。它是面向模型的 id(模型会把 `job_id` 传回 `bash_output`/`bash_kill`),所以该混淆可由不受信任的输入触达。 -bash **owner token** 是相关的子情形:`BashExecRequest.owner?: string` 和 `BashExecSpec.owner: string | undefined`(`packages/bash/bash/src/types.ts`)被文档描述为刻意*不透明*的隔离键,但在所有实际调用方中,该值就是所属 agent 共享的 `Agent.id`/`SessionId`(`callerToken = (exec) => exec.agent?.id`,位于 `packages/bash/tool-bash/src/index.ts`),只是披着另一个 seam 本地名称。它被用于访问控制比较(`owner !== callerToken(exec)`),因此一个不匹配但类型正确的 string 在此处就是跨会话隔离 bug,而当前类型系统无法捕获。这正是[统一 agent/session 标识决策](../simplification/2026-06-20-unify-agent-and-session-id.md)覆盖的共享 id 别名。 +bash **owner token** 是相关的子情形:`ShellExecRequest.owner?: string` 和 `ShellExecSpec.owner: string | undefined`(`packages/shell/shell/src/types.ts`)被文档描述为刻意*不透明*的隔离键,但在所有实际调用方中,该值就是所属 agent 共享的 `Agent.id`/`SessionId`(`callerToken = (exec) => exec.agent?.id`,位于 `packages/shell/tool-bash/src/index.ts`),只是披着另一个 seam 本地名称。它被用于访问控制比较(`owner !== callerToken(exec)`),因此一个不匹配但类型正确的 string 在此处就是跨会话隔离 bug,而当前类型系统无法捕获。这正是[统一 agent/session 标识决策](../simplification/2026-06-20-unify-agent-and-session-id.md)覆盖的共享 id 别名。 **缺口 2:*已经 brand* 的 ID 在边界处被侵蚀。** 就连 `CallId` 和 `SessionId` 也恰好在最容易混淆的地方退化为裸 `string`:注册表/store 键类型和公开方法参数。代表性位置包括会话存储、agent 注册表(二者都以共享的 `SessionId` 为键)、工具展示层的 call-id map、ACP(Agent Client Protocol)的会话记录,以及持久化协调器。在集合键处丢弃 brand,会让既有 brand 在查找时毫无价值;它们的价值只实现了一部分。 @@ -18,9 +18,9 @@ bash **owner token** 是相关的子情形:`BashExecRequest.owner?: string` 纯类型变更。Brand 是零开销 cast;运行时行为、序列化、比较和协议格式(wire format)均不变。该决策分三部分,全部遵循既有的「不是每个 string 都需要」策略。 -- **为 bash task id 加 brand。** 在 `packages/bash/bash/src/types.ts`(*拥有*该 id 的包)中添加 `BashTaskId = Branded<'BashTaskId'>` 及其同名工厂,从 `@deepseek-ai/dsh-brand` 导入 `Branded`,方式与 `SessionId` 完全一致。brand 原语位于无依赖的 `dsh-brand` 工具包中,正是为了让 `dsh-bash` 仅依赖它就能为自己的 id 加 brand,而无需引入 `dsh-llm`(或 `dsh-session`)来获取 `Branded`。将其贯穿 `BashTask.id`、`BashExecutor` Service Definition 方法(`get`/`ownerOf`/`readOutput`/`kill`)、`dsh-bash-local` 中的生成点(在创建时对计数器输出做一次 brand),以及 `dsh-tool-bash` 的校验/访问面(`validateTaskId` 返回 `BashTaskId`;`task_id` 在模型 string 到达的工具边界处被 brand)。 +- **为 bash job id 加 brand。** 在 `packages/shell/shell/src/types.ts`(*拥有*该 id 的包)中添加 `BashTaskId = Branded<'BashTaskId'>` 及其同名工厂,从 `@deepseek-ai/dsh-brand` 导入 `Branded`,方式与 `SessionId` 完全一致。brand 原语位于无依赖的 `dsh-brand` 工具包中,正是为了让 `dsh-shell` 仅依赖它就能为自己的 id 加 brand,而无需引入 `dsh-llm`(或 `dsh-session`)来获取 `Branded`。将其贯穿 `BashTask.id`、`ShellExecutor` Service Definition 方法(`get`/`ownerOf`/`readOutput`/`kill`)、`dsh-bash-local` 中的生成点(在创建时对计数器输出做一次 brand),以及 `dsh-tool-bash` 的校验/访问面(`validateJobId` 返回 `BashTaskId`;`job_id` 在模型 string 到达的工具边界处被 brand)。 -- **铸造独立的 `OwnerToken` brand。** 在 `packages/bash/bash/src/types.ts` 中添加 `OwnerToken = Branded<'OwnerToken'>`;将 `BashExecRequest.owner` / `BashExecSpec.owner` / `BashExecutor.ownerOf` 的类型标注为 `OwnerToken | undefined`。`dsh-tool-bash` 消费方在边界处将 agent 共享的 `id`(`SessionId`)cast 为 `OwnerToken`——这是两套词汇唯一交汇的地方。bash Service Definition 从不导入 `dsh-session`。(理由见下一节。) +- **铸造独立的 `OwnerToken` brand。** 在 `packages/shell/shell/src/types.ts` 中添加 `OwnerToken = Branded<'OwnerToken'>`;将 `ShellExecRequest.owner` / `ShellExecSpec.owner` / `ShellExecutor.ownerOf` 的类型标注为 `OwnerToken | undefined`。`dsh-tool-bash` 消费方在边界处将 agent 共享的 `id`(`SessionId`)cast 为 `OwnerToken`——这是两套词汇唯一交汇的地方。bash Service Definition 从不导入 `dsh-session`。(理由见下一节。) - **阻止 brand 侵蚀。** 将既有 brand 传播到缺口 2 列出的 `Map` 键类型和公开方法参数中:`Map`、`Map`、`get(id: SessionId)`、`Map`、ACP 的 `SessionId` surface、协调器的 `Map`。这是变更中机械量最大的部分,也是让*既有* brand 在查找处真正发挥作用(而不仅仅标注在结构体字段上)的关键。 @@ -46,21 +46,21 @@ export function OwnerToken(id: string): OwnerToken { ### 为什么不把 `owner` 类型标注为 `SessionId`? -显而易见的捷径是直接把 `owner` 类型标注为 `SessionId`——它确实*总是*一个会话 id。我们否决这个方案。bash 执行器 seam 是能力 seam(Service Definition `dsh-bash`、Service provider `dsh-bash-local`、Consumer `dsh-tool-bash`),其 owner token 被*明确记录为刻意不透明*:执行器「从不解释它(seam 中没有访问策略——那是消费方的职责)」(`packages/bash/bash/src/types.ts`)。把 Service Definition 的字段类型标注为 `SessionId`,会把 `dsh-session` 的词汇引入一个不应知道 owner token *含义*的包——这会让通用执行后端耦合会话模型,并违背不透明 token 的设计。取代 `dsh-bash-local` 的沙箱化执行器或远程执行器不应继承会话依赖。独立的 `OwnerToken` brand 使 seam 保持解耦:`dsh-bash` 只知道「owner 是某种带 brand 的不透明 token」,而已经决定访问策略的 `dsh-tool-bash` 消费方,是把其 `SessionId` cast 为 `OwnerToken` 的唯一边界。该 brand 仍带来安全收益(不能把 `BashTaskId` 或裸 string 传到 owner 位置),且不引入耦合。 +显而易见的捷径是直接把 `owner` 类型标注为 `SessionId`——它确实*总是*一个会话 id。我们否决这个方案。bash 执行器 seam 是能力 seam(Service Definition `dsh-shell`、Service provider `dsh-bash-local`、Consumer `dsh-tool-bash`),其 owner token 被*明确记录为刻意不透明*:执行器「从不解释它(seam 中没有访问策略——那是消费方的职责)」(`packages/shell/shell/src/types.ts`)。把 Service Definition 的字段类型标注为 `SessionId`,会把 `dsh-session` 的词汇引入一个不应知道 owner token *含义*的包——这会让通用执行后端耦合会话模型,并违背不透明 token 的设计。取代 `dsh-bash-local` 的沙箱化执行器或远程执行器不应继承会话依赖。独立的 `OwnerToken` brand 使 seam 保持解耦:`dsh-shell` 只知道「owner 是某种带 brand 的不透明 token」,而已经决定访问策略的 `dsh-tool-bash` 消费方,是把其 `SessionId` cast 为 `OwnerToken` 的唯一边界。该 brand 仍带来安全收益(不能把 `BashTaskId` 或裸 string 传到 owner 位置),且不引入耦合。 ## 不在范围内 / 可能的扩展 遵循「不是每个 string 都需要 brand」的策略,刻意保持窄范围。以下每项都是合理的未来 brand 候选,附带推迟理由而非承诺: -- **`ModelId`**(`GenerateOptions.model`,`LlmService` 适配器注册表的键):一个真正的跨包查找键(config → agent → llm → 适配器);合理的下一个 brand,仅为控制本决策的影响范围而暂不纳入。 -- **`ToolName`**(`ToolRegistry` 的键):由作者定义、人类可读,且很少与其他 id 混淆;最弱的候选,可能不值得加 brand。 +- **`ModelId`**(`GenerateOptions.model`,`LlmRuntime` 适配器注册表的键):一个真正的跨包查找键(config → agent → llm → 适配器);合理的下一个 brand,仅为控制本决策的影响范围而暂不纳入。 +- **`ToolName`**(`ToolRuntime` 的键):由作者定义、人类可读,且很少与其他 id 混淆;最弱的候选,可能不值得加 brand。 - **`ErrorCode`**(`HarnessError.code`):一个封闭词汇(`ABORTED`、`NO_ADAPTER`……),不是逐实例的 id;如果要做,string 字面量联合类型比 brand 更合适。 - **数值序号**:轮次号、步骤号和事件 `seq` 是 `number` 而非 `string`,`Branded` 不适用;可以用并行的 `number & { readonly [BRAND]: B }` 变体来 brand 它们,但它们是位置序号、很少跨边界传递,收益较低。 - **带校验的构造**:brand 工厂是纯 cast,无运行时检查,且每个边界(ACP `sessionId`、提供方签发的 `call.id`、`dsh-llm-deepseek` 中的空字符串回退)今天都信任裸 string。一个在边界处对格式错误的输入抛异常的 `SessionId.parse()` / `isValid()` 配套工具确实是缺口,但它是*运行时行为*变更,有自己的设计问题(什么算「格式错误」?失败时会怎样?),应在独立决策中处理,不应捆绑进这次纯类型变更。 ## 验证 -已落地的不变式如下:`BashTaskId` 和 `OwnerToken` 定义在 `dsh-bash` 中,并端到端贯穿 Service Definition、`dsh-bash-local` 生成点与 `dsh-tool-bash` 面向模型的工具,且 `dsh-bash` 未添加对 `dsh-session` 的依赖;没有任何以范围内 brand id(`CallId`/`SessionId`/`BashTaskId`)为键的集合使用裸 `string`;公开方法参数和导出签名保留 brand;每个原始 string 进入的边界(提供方 call id、ACP 会话 id、模型提供的 `task_id`)都通过 cast 工厂构造 brand,而不是散落的 `as` cast。 +已落地的不变式如下:`BashTaskId` 和 `OwnerToken` 定义在 `dsh-shell` 中,并端到端贯穿 Service Definition、`dsh-bash-local` 生成点与 `dsh-tool-bash` 面向模型的工具,且 `dsh-shell` 未添加对 `dsh-session` 的依赖;没有任何以范围内 brand id(`CallId`/`SessionId`/`BashTaskId`)为键的集合使用裸 `string`;公开方法参数和导出签名保留 brand;每个原始 string 进入的边界(提供方 call id、ACP 会话 id、模型提供的 `job_id`)都通过 cast 工厂构造 brand,而不是散落的 `as` cast。 ## 后果 diff --git a/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.i18n.yaml b/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.i18n.yaml index 088891c738..3480f0b231 100644 --- a/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.i18n.yaml @@ -2,5 +2,5 @@ # 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 .agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md -2026-06-20-generic-long-running-tool-runtime.md: 1edc3422c253e06178a5c8ebf68dfd4ef1289e31 -2026-06-20-generic-long-running-tool-runtime.zh.md: 1f5349b2aeb02e8db21150012300a6d0a0493ae1 +2026-06-20-generic-long-running-tool-runtime.md: 7db43323dd83f8e99698a7163412c9b33a607dfb +2026-06-20-generic-long-running-tool-runtime.zh.md: fe12ef264d294224fcfaf503ba958fa90c782347 diff --git a/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md b/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md index 1edc3422c2..7db43323dd 100644 --- a/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md +++ b/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md @@ -1,4 +1,4 @@ -# Agent Note: The background task runtime (`ctx.tasks`) and generic task control tools +# Agent Note: The background job runtime (`ctx.jobs`) and generic task control tools Status: implemented @@ -6,38 +6,38 @@ English | [中文](2026-06-20-generic-long-running-tool-runtime.zh.md) ## Problem -Background bash originally combined two responsibilities: the bash executor ran processes and also managed task ids, ownership, incremental reads, cancellation, completion listeners, and model-facing control tools. Adding background subagents required the same lifecycle and interaction contract. Implementing that contract independently for every long-running capability would duplicate isolation, cleanup, notification, and prompt behavior while teaching the model a different collect-and-stop protocol for each producer. +Background bash originally combined two responsibilities: the bash executor ran processes and also managed job ids, ownership, incremental reads, cancellation, completion listeners, and model-facing control tools. Adding background subagents required the same lifecycle and interaction contract. Implementing that contract independently for every long-running capability would duplicate isolation, cleanup, notification, and prompt behavior while teaching the model a different collect-and-stop protocol for each producer. -The task registry, control tools, and completion notices form one harness capability. Bash and subagents should supply execution-specific hooks without owning generic task behavior. +The job registry, control tools, and completion notices form one harness capability. Bash and subagents should supply execution-specific hooks without owning generic task behavior. ## Decision -The `tasks/` package group owns background-task semantics: +The `jobs/` package group owns background-job semantics: -- `@deepseek-ai/dsh-tasks` registers running work as `ctx.tasks` and owns task ids, authorization, snapshots, reads, cancellation, waiting, completion listeners, and cleanup. -- `@deepseek-ai/dsh-tool-tasks` exposes `task_output`, `task_list`, and `task_kill`, injects completion notices, and supplies the background-task system-prompt guidance. +- `@deepseek-ai/dsh-jobs` registers running work as `ctx.jobs` and owns job ids, authorization, snapshots, reads, cancellation, waiting, completion listeners, and cleanup. +- `@deepseek-ai/dsh-tool-jobs` exposes `job_output`, `job_list`, and `job_kill`, injects completion notices, and supplies the background-job system-prompt guidance. -Long-running tools are producers. `dsh-tool-bash` adapts a `BashProcess` into incremental output and process cancellation; `dsh-tool-subagent` adapts a child run into final output and child disposal. The bash and subagent capability seams remain independent of sessions and the task registry. +Long-running tools are producers. `dsh-tool-bash` adapts a `ShellProcess` into incremental output and process cancellation; `dsh-tool-subagent` adapts a child run into final output and child disposal. The bash and subagent capability seams remain independent of sessions and the job registry. -`TaskService` is the Service Definition in `@deepseek-ai/dsh-tasks`; the process-local provider is `LocalTaskService` in `@deepseek-ai/dsh-tasks-local` (the [task-registry contract Agent Note](2026-07-26-task-registry-seam.md) records that split). +`JobRegistry` is the Service Definition in `@deepseek-ai/dsh-jobs`; the process-local provider is `LocalJobRegistry` in `@deepseek-ai/dsh-jobs-local` (the [task-registry contract Agent Note](2026-07-26-job-registry-seam.md) records that split). ## Runtime contract -The literal types live on the [tasks subsystem page](../../../../docs/subsystems/tasks.md). A producer calls `ctx.tasks.start()` with a kind, label, optional owning `Agent`, optional positive `outputLimitBytes`, and a `run()` function. The runtime completes all failable preflight work before calling `run()` and invokes it once. After `run()` returns hooks, registration commits without another failable step; a producer cannot start work that lacks a collectable task id. +The literal types live on the [tasks subsystem page](../../../../docs/subsystems/jobs.md). A producer calls `ctx.jobs.start()` with a kind, label, optional owning `Agent`, optional positive `outputLimitBytes`, and a `run()` function. The runtime completes all failable preflight work before calling `run()` and invokes it once. After `run()` returns hooks, registration commits without another failable step; a producer cannot start work that lacks a collectable job id. -The process-local provider also owns bounded admission, whose rationale is recorded in the [bounded background task admission decision](../bug-fix/2026-08-11-bounded-background-task-admission.md). Its positive-safe-integer `maxConcurrentTasksPerOwner` config defaults to `10`; `start()` derives each exact `Agent` object's active count from `running` and `stopping` records, while every unowned task shares one service bucket. Capacity rejection occurs before `run()` and id allocation, and producer `done` settlement is the only event that releases a stopping task's place. The provider does not queue, preempt, or retain a second mutable count. +The process-local provider also owns bounded admission, whose rationale is recorded in the [bounded background job admission decision](../bug-fix/2026-08-11-bounded-background-job-admission.md). Its positive-safe-integer `maxConcurrentJobsPerOwner` config defaults to `10`; `start()` derives each exact `Agent` object's active count from `running` and `stopping` records, while every unowned task shares one service bucket. Capacity rejection occurs before `run()` and id allocation, and producer `done` settlement is the only event that releases a stopping task's place. The provider does not queue, preempt, or retain a second mutable count. -`outputLimitBytes` is producer-owned presentation policy, not a registry buffer. The registry validates and projects it unchanged into `TaskSnapshot`; generic control APIs apply the cap to complete model-facing output after adding their own status or notice metadata. Omitting it preserves the existing controller behavior, so the runtime does not impose a hidden default on unrelated producer families. +`outputLimitBytes` is producer-owned presentation policy, not a registry buffer. The registry validates and projects it unchanged into `JobSnapshot`; generic control APIs apply the cap to complete model-facing output after adding their own status or notice metadata. Omitting it preserves the existing controller behavior, so the runtime does not impose a hidden default on unrelated producer families. -A model-facing producer exposes that committed id in its canonical success value, normally `{ kind: 'background', taskId }`; Native rendering may keep human-readable prose. A pre-aborted background call fails rather than returning a no-op because no task exists to satisfy the promised handle. Once registration publishes the id, cancellation belongs to the task's own controller and the task runtime: later cancellation of the producing tool call must not kill the published task. `task_kill`, owner disposal, and service teardown request cancellation; foreground execution remains coupled to the call's `exec.signal`. +A model-facing producer exposes that committed id in its canonical success value, normally `{ kind: 'background', jobId }`; Native rendering may keep human-readable prose. A pre-aborted background call fails rather than returning a no-op because no task exists to satisfy the promised handle. Once registration publishes the id, cancellation belongs to the task's own controller and the job runtime: later cancellation of the producing tool call must not kill the published task. `job_kill`, owner disposal, and service teardown request cancellation; foreground execution remains coupled to the call's `exec.signal`. The producer hooks define three responsibilities: - `cancel(reason?)` synchronously requests termination, is idempotent, and must cause `done` to settle. - `done` never rejects and settles only after the producer has released the task's resources. -- Optional `readOutput()` returns the next consuming output delta. Omitting it declares a final-output task whose terminal result comes from `TaskOutcome.output`. +- Optional `readOutput()` returns the next consuming output delta. Omitting it declares a final-output task whose terminal result comes from `JobOutcome.output`. -Statuses are `running`, `stopping`, `completed`, `killed`, and `failed`. Producer-specific information such as an exit code or stop reason belongs in `detail`; the registry does not interpret it. Task kinds form a merge-extensible string union, and task ids are branded and generated as `-N`, with a counter per kind. +Statuses are `running`, `stopping`, `completed`, `killed`, and `failed`. Producer-specific information such as an exit code or stop reason belongs in `detail`; the registry does not interpret it. Task kinds form a merge-extensible string union, and job ids are branded and generated as `-N`, with a counter per kind. The runtime attaches one continuation to `done`, records the first terminal outcome, resolves waiters, and invokes completion listeners with per-listener error containment. First-wins settlement matters during teardown: if `cancel` throws, the runtime force-fails the record and warns that work may be orphaned rather than waiting forever for a promise that may never settle. A later producer outcome cannot overwrite that diagnosis or notify twice. A `cancel` that returns without eventually settling `done` still blocks teardown because the runtime cannot distinguish it from a slow, valid stop. @@ -45,7 +45,7 @@ Task registrations are not effects of the producer tool fiber. Reloading a tool ## Authorization and owner lifecycle -Task ids are runtime-global and predictable, so every access is authorized by the registry. `get`, `read`, `wait`, and `kill` accept the calling `Agent`; `list` returns only tasks visible to that caller. An owned task is accessible only to the exact owning session. Unowned tasks are open to non-agent callers and die with the task service. +Job ids are runtime-global and predictable, so every access is authorized by the registry. `get`, `read`, `wait`, and `kill` accept the calling `Agent`; `list` returns only tasks visible to that caller. An owned task is accessible only to the exact owning session. Unowned tasks are open to non-agent callers and die with the task service. The snapshot stores the owner's branded `SessionId` for authorization, while lifecycle operations retain the exact live `Agent` instance. These identities serve different purposes: session equality grants access, but exact object identity selects cleanup and completion delivery. Reusing an agent or session id cannot redirect an old scope's cleanup or notices to a replacement. @@ -55,45 +55,45 @@ For contract-compliant producers, `AgentHandle.dispose()` resolves only after ow ## Service API -`TaskService` provides: +`JobRegistry` provides: - `start(spec)` for preflighted, provider-admitted, atomic registration. - `get(id, caller?)` and `list(caller?)` for non-consuming snapshots. - `read(id, caller?)` for a consuming stream delta or an idempotent final result. - `kill(id, caller?, reason?)` for cancellation. - `wait(id, timeoutMs, caller?, signal?)` for bounded terminal waiting. -- `onTaskDone(listener)` for effect-scoped observation with exact-owner delivery and listener containment. +- `onJobDone(listener)` for effect-scoped observation with exact-owner delivery and listener containment. - `attachController(name)` for the task-controller availability fence. `wait` returns the terminal snapshot when the task settles or the live snapshot when its timeout expires. Aborting a wait cancels only that wait. If settlement has already assigned terminal delivery to the waiter, the terminal snapshot still wins. Waiters unregister synchronously on abort so a same-tick settlement cannot suppress a completion notice on behalf of a reader that receives nothing. -A producer loaded without any controller would let callers start work they cannot collect or stop. `dsh-tool-tasks` therefore calls `attachController()` for its lifetime, and `start()` fails before producer execution when no controller is attached. This check occurs at start rather than plugin load because sibling plugins may activate concurrently. Custom non-model controllers can attach themselves without teaching the registry tool names. +A producer loaded without any controller would let callers start work they cannot collect or stop. `dsh-tool-jobs` therefore calls `attachController()` for its lifetime, and `start()` fails before producer execution when no controller is attached. This check occurs at start rather than plugin load because sibling plugins may activate concurrently. Custom non-model controllers can attach themselves without teaching the registry tool names. ## Model-facing control API -`dsh-tool-tasks` registers three kind-independent tools with generic UI cards: +`dsh-tool-jobs` registers three kind-independent tools with generic UI cards: -- `task_output(task_id, wait?, timeout_ms?)` reads output and always appends `[status: ...]`. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Reads are non-blocking unless `wait: true`, whose timeout is defaulted and capped by plugin config. A wait timeout reports the still-running status and does not stop the task. -- `task_list()` returns caller-visible tasks as ` []