docs(i18n): proofread README translations 21-40

This commit is contained in:
j-xiang
2026-07-29 15:29:38 +08:00
parent 333b4bcd30
commit 90c75be466
20 changed files with 104 additions and 104 deletions

View File

@@ -2,9 +2,9 @@
[English](README.md) | 中文
为通过 fetch 到达的客户端插件提供热重载。该静态到达配置项只组合进 `--dev` 图(`dsh web --dev`);生产图省略此行,因此外壳打包的代码保持不活动。
为通过 fetch 加载的客户端插件提供热重载。该静态加载配置项只组合进 `--dev` 图(`dsh web --dev`);生产图省略该项,因此打包进 shell 的代码保持不活动。
浏览器侧订阅系统 SSE 通道(`GET /plugins/events`),每个 `rebuilt` 帧重载一个插件,并通过队列串行执行(组合包交接 slot 只能容纳一个)。每帧的顺序是:`prefetch`(在触碰任何内容前抓取新组合包)、`invalidate``registry.delete`(在 fiber 之前执行:只释放 fiber 会触发 vendored Loader 的 self-dispose 分支,把配置项标为禁用)、排空旧 fiber、删除 `entry.fiber`、移除自身拥有的 `<style data-plugin>` 标签、通过 `entry.refresh()` 重新导入并挂载、 `fiber.await()` 将启动失败高声重新抛出。依赖方由 cordis 自身重载fiber 的激活 epoch 会串联其服务提供方的 uid因此替换提供方 fiber 会级联所有依赖方无需客户端图分析。node 侧使用一个 interval 检测重建:从同步基线开始 stat-poll 每个图组合包;新增一行后立即重新计算 hash缺失行保持 dirty只广播真实 rev 变更。因此,任何生成组合包的 tsdown watch 进程都能触发 HMR无需 builder→host 通道。
浏览器侧订阅系统 SSEServer-Sent Events通道(`GET /plugins/events`),每个 `rebuilt` 帧重载一个插件,并通过队列串行执行(组合包交接 slot 只能容纳一个)。每帧的顺序是:`prefetch`(在触碰任何内容前抓取新组合包)、`invalidate``registry.delete`(在 fiber dispose资源释放之前执行仅 dispose fiber 会触发 vendored Loader 的 self-dispose 分支,把配置项标为禁用)、排空旧 fiber、删除 `entry.fiber`、移除自身拥有的 `<style data-plugin>` 标签、通过 `entry.refresh()` 重新导入并挂载、通过 `fiber.await()` 直接重新抛出启动失败。依赖方由 Cordis 自身重载fiber 的激活 epoch 会串联其服务提供方的 uid因此替换提供方 fiber 会级联所有依赖方无需客户端图分析。node 侧使用一个 interval 检测重建:从同步基线开始 stat-poll 每个图组合包;新增一行后立即重新计算 hash缺失行保持 dirty只广播真实 rev 变更。因此,任何生成组合包的 tsdown watch 进程都能触发 HMR(热模块替换),无需 builder→host 通道。
## 模型体验
@@ -12,10 +12,10 @@
#### KV Cache 影响
无;该包既不组装也不发送提供方请求。
无;该包package既不组装也不发送提供方请求。
## 已知限制与暂缓事项
- **重载有意保持粗粒度**:会创建全新的 fiber 和组件;重载插件中的 React 状态会丢失,数据层(connection/runtime fiberSession 对象不受影响。react-refresh 级状态保留与「重新执行组合包会重新运行 factory」冲突因此有意排除。
- **失败时不回滚**:失败的重载会使配置项处于 FAILED 状态,并在 loader 状态投影中高声报告;自动恢复先前组合包会等到实际需要出现后再实现。
- **重建帧不会刷新图 rev**:陈旧 rev 无害(组合包端点以 no-cache 提供内容rev 刷新会随重新连接握手机制落地
- **重载有意保持粗粒度**:会创建全新的 fiber 和组件;重载插件中的 React 状态会丢失,数据层(连接 fiber、运行时 fiberSession 对象不受影响。react-refresh 级状态保留与「重新执行组合包会重新运行 factory」冲突因此有意排除。
- **失败时不回滚**:失败的重载会使配置项处于 FAILED 状态,并在 loader 状态投影中明确显示;自动恢复先前组合包会等到实际需要出现后再实现。
- **重建帧不会刷新图 rev**:陈旧 rev 无害(组合包端点以 no-cache 提供内容rev 刷新将在重新连接握手机制中实现

View File

@@ -10,9 +10,9 @@ locale 插件LocaleService 包含浏览器 locale 偏好(`zh``en`,以
#### KV Cache 影响
无;该包既不组装也不发送提供方请求。
无;该包package既不组装也不发送提供方请求。
## 已知限制与暂缓事项
- **只有设置界面完成翻译**:其他页面仍保留内联文案;将全仓文案提取到字典的工作暂缓。
- **切换 locale 只重新渲染已订阅的消费方**:未接入 `locale/change`分区会保留已渲染文本,直到重新挂载。
- **切换 locale 只重新渲染已订阅的消费方**:未接入 `locale/change`界面区域会保留已渲染文本,直到重新挂载。

View File

@@ -2,11 +2,11 @@
[English](README.md) | 中文
客户端模块系统Node 内部 ESM loader 的浏览器端对等实现,以惰性 CJS 表构建。web 外壳挂载 vendored cordis Loader 来治理配置项fiber 生命周期、inject 等待、update/refresh并把该包的 `ClientModuleLoader` 作为其 `internal` seam 注入vendored 一侧唯一的消费点是 `EntryTree.import`,因此替换 `internal` 恰好只会替换「插件代码如何到达」,不会改变其他内容。
客户端模块系统Node 内部 ESM loader 的浏览器端对等实现,以惰性 CJS 表实现。web 外壳挂载 vendored cordis Loader 来治理配置项fiber 生命周期、inject 等待、update/refresh并把该包package`ClientModuleLoader` 作为其 `internal` seam 注入vendored 一侧唯一的消费点是 `EntryTree.import`,因此替换 `internal` 恰好只会替换「插件代码如何到达」,不会改变其他内容。
惰性 CJS 模型web2执行插件组合包只会注册其 factory`window.__ModuleLoader__.load({id, factory})`);每个模块主体的副作用(包括 CSS 注入)都位于 factory 闭包中,在物化时运行(`factory(require)` → 导出表层,并在 `loadCache` 中记忆化),不会在脚本执行时运行。如果 factory 请求另一个已注册但尚未物化的模块系统会递归物化它因此加载顺序无需外部编排require 循环会抛出异常factory 形式的 CJS 无法交付部分导出)。`<id>/client` 与裸 id 指向同一表层(一个插件组合包就是其包的客户端侧)。
惰性 CJS 模型web2执行插件组合包只会注册其 factory`window.__ModuleLoader__.load({id, factory})`);每个模块主体的副作用(包括 CSS 注入)都位于 factory 闭包中,在物化时运行(`factory(require)` → 导出表层,并在 `loadCache` 中记忆化),不会在脚本执行时运行。如果 factory 依赖另一个已注册但尚未物化的模块系统会递归物化它因此加载顺序无需外部编排require 循环会抛出异常factory 形式的 CJS 无法提供部分导出)。`<id>/client` 与裸 id 指向同一表层(一个插件组合包就是其包的客户端侧)。
解析分支顺序(`import(specifier)`):平台种子词 → 外壳实例;记忆化记录 → 表层;外壳自身的静态注册表(`registerStatic`app-shell→ 模块;已注册 factory → 物化;图行`window.__DSH_BOOT__`)→ 抓取 + 执行 + 物化;其他情况一律抛出异常。这是构建时组合包纯度门禁的运行时镜像。交给 factory 的同步 `require` 采用相同顺序,但不含抓取分支,并把观察到的边记录到模块记录中。`prefetch` 是第一阶段到达 hook(抓取 + 执行,只注册;并发调用共享一个进行中的 task`invalidate` 会丢弃 factory 与物化记录,使下一次 prefetch/import 重新抓取HMR hook
解析分支顺序(`import(specifier)`):平台种子词 → 外壳实例;记忆化记录 → 表层;外壳自身的静态注册表(`registerStatic`app-shell→ 模块;已注册 factory → 物化;模块图记录`window.__DSH_BOOT__`)→ 抓取 + 执行 + 物化;其他情况一律抛出异常。这是构建时组合包纯度门禁的运行时镜像。交给 factory 的同步 `require` 采用相同顺序,但不含抓取分支,并把观察到的边记录到模块记录中。`prefetch` 是第一阶段加载钩子(抓取 + 执行,只注册;并发调用共享一个进行中的任务`invalidate` 会丢弃 factory 与物化记录,使下一次 prefetch/import 重新抓取;它是 HMR热模块替换钩子
## 模型体验
@@ -18,5 +18,5 @@
## 已知限制与暂缓事项
- **有意采用扁平模块图**:每个组合包是一个模块节点,其边只指向表接口loadCache/edges/invalidate按通用模块图塑形因此可以改变 externalization 粒度而不更改接口。
- **自身不记录卸载账目**:样式移除与 fiber 拆卸顺序属于 HMR 驱动器(`@deepseek-ai/dsh-client-hmr`loader 只逐记录清点自身拥有的样式标签 id。
- **有意采用扁平模块图**:每个组合包是一个模块节点,其边只指向表中的叶节点接口loadCache/edges/invalidate按通用模块图塑形因此可以改变 externalization 粒度而不更改接口。
- **自身不记录卸载账目**:样式移除与 fiber 拆卸顺序属于 HMR 驱动器(`@deepseek-ai/dsh-client-hmr`loader 只在每条记录中登记其拥有的样式标签 id。

View File

@@ -2,19 +2,19 @@
[English](README.md) | 中文
客户端 cordis 启动与不依赖 React 的对象服务SlotsService 包装 SlotCore 并提供 renderer 数据源SessionsService 拥有 Session 对象、列表scopehistory 状态WorkspacesService 依赖 SessionsService拥有 Workspace 对象、列表/操作、默认目标派生,以及 New Session 空会话复用入口(`connectWorkspace`)。运行时把共享 Host 流分发给两个 manager。客户端 Session 一律由 Host 出生(一次 `session.create`瞬产出 Session+Agent+cwd客户端不持有任何实体化之前的会话状态——Agent scopehost dsh-scope 的客户端镜像,以 agent/session 共用 id 为键)在会话行进入列表镜像时出生,随 prune 死亡。契约api-contracts v3 §4。每个 `Session` 持有一个通用的 `ProjectionValueStore`,由历史尾`projections` 块播种,并经 `session/projection` 帧按 seq 高者胜更新;领域键(含 `todos`)经 `projections.faceOf``useProjection` 读取,不经 `ConversationSnapshot`
客户端 cordis 启动与不依赖 React 的对象服务SlotsService 包装 SlotCore 并提供 renderer 数据源SessionsService 拥有 Session 对象、列表scopehistory 状态WorkspacesService 依赖 SessionsService拥有 Workspace 对象、列表/操作、默认目标派生,以及 New Session 空会话复用入口(`connectWorkspace`)。运行时把共享 Host 流分发给两个 manager。客户端会话一律由 Host 创建(一次 `session.create`时产生 Session、agent(智能体)和 cwd客户端不持有任何实体化之前的会话状态——agent scopehost dsh-scope 的客户端镜像,以 agent/session 共用 id 为键)在会话行进入列表镜像时创建,并随 prune 销毁。契约api-contracts v3 §4。每个 `Session` 持有一个通用的 `ProjectionValueStore`,由历史记录末尾的 `projections` 块播种,并经 `session/projection` 帧按 seq 高者胜更新;领域键(含 `todos`)经 `projections.faceOf``useProjection` 读取,不经 `ConversationSnapshot`
## Workspace 与 Session 列表
Workspace 和 Session 列表各自具有单调的 `pending``ready` 基线阶段,也有各自的刷新活动/错误状态。列表请求期间到达的增量更新/移除帧与一元变更回显会在其响应之上回放。第一次成功的基线建立 Host 顺序;后续刷新更新行和成员关系,但不改变已经显示的标识之间的相对顺序。已移除的 Workspace id 会保留进程本地删除标记,避免延迟到达的 changed 帧将其复活;重连仍以 `workspace.list` 作为基线。Workspace 新近程度只在两条基线都 ready 后派生,且绝不改变 Workspace 列表顺序。
Workspace 和 Session 列表各自具有单调的 `pending``ready` 基线阶段,也有各自的刷新活动/错误状态。列表请求期间到达的增量插入或更新/移除帧与一元变更回显会在其响应之上回放。第一次成功的基线建立 Host 顺序;后续刷新更新行和成员关系,但不改变已经显示的标识之间的相对顺序。已移除的 Workspace id 会保留进程本地删除标记,避免延迟到达的 changed 帧将其复活;重连仍以 `workspace.list` 作为基线。Workspace 新近程度只在两条基线都 ready 后派生,且绝不改变 Workspace 列表顺序。
`WorkspacesService.delete(workspaceId)` 在一元响应成功后从客户端投影中移除注册记录;对应的 `host/workspace-removed` 帧具有幂等性并负责同步其他标签页。Session 状态与当前 Session selection 相互独立,因此 Workspace 消失后,其已记账的 Session 会立即投影到 Ungrouped 下。
`WorkspacesService.delete(workspaceId)` 在一元响应成功后从客户端投影中移除注册记录;对应的 `host/workspace-removed` 帧具有幂等性并负责同步其他标签页。Session 状态与当前 Session selection 相互独立,因此 Workspace 消失后,其已纳入客户端投影的 Session 会立即投影到 Ungrouped 下。
SlotsService 分别为 renderer 提供 `useSessions``useWorkspaces` 的裸 observableweb-react 创建 hook。Workspace 业务状态不会进入 `SessionListState` 或配置项 store。
SlotsService 分别为 renderer 提供 `useSessions``useWorkspaces` 的裸 observableweb-react 创建钩子。Workspace 业务状态不会进入 `SessionListState` 或配置项 store。
## New Session 与 blank 镜像
`WorkspacesService.connectWorkspace(workspaceId)` 解析 New Session 流程最终落入的会话:先在列表镜像中复用该 workspace 的既有空会话(`blank && cwd == workspace.path`),未命中则调用 `session.create({workspaceId})`,返回会话 id 由调用方 open。`SessionSummary.blank` 镜像主机派生的空日志位,在客户端只降不升:由 `session.list``host/session-added` 帧播种,本地首次**受理成功**`prompt()`RPC 成功响应时——受理即证明用户消息已入主机日志;首讯被拒则会话保持 blank、保持可复用与任何 `running: true` 状态帧翻为 false每次列表重拉重新对齐。列表面隐藏 blank 行store 保留全部行。`SessionsService.create` 接受可选的、由调用方预先分配的 SessionId失败时抛出 `SessionCreateError`(携带 `requestedSessionId`)。
`WorkspacesService.connectWorkspace(workspaceId)` 解析 New Session 流程最终落入的会话:先在列表镜像中复用该 workspace 的既有空会话(`blank && cwd == workspace.path`),未命中则调用 `session.create({workspaceId})`,返回会话 id 由调用方 open。`SessionSummary.blank` 镜像主机派生的空日志位,在客户端只降不升:由 `session.list``host/session-added` 帧播种,本地首次获 Host 接受`prompt()`RPC 成功响应时——受理即证明用户消息已入主机日志;首讯被拒则会话保持 blank、保持可复用与任何 `running: true` 状态帧翻为 false每次列表重拉重新对齐。列表面隐藏 blank 行store 保留全部行。`SessionsService.create` 接受可选的、由调用方预先分配的 SessionId失败时抛出 `SessionCreateError`(携带 `requestedSessionId`)。
## Code Mode 子调用索引
@@ -22,7 +22,7 @@ SlotsService 分别为 renderer 提供 `useSessions` 与 `useWorkspaces` 的裸
## Session 标题投影
`SessionManager` 独立于列表和 Session 实例到达情况,保留最近一次通过验证的 `session/title` 控制快照。seq 更的事件会替换旧快照,标题时间戳计入列表新近程度;订阅基线会先丢弃 seq 超过其 `lastSeq` 的任何已保留标题,再接收可选的折叠标题。显式移除 Session 也会清除已保留标题。因此,面向客户端的 `SessionSummary.title` 只包含实的持久标题;`displayTitle` 始终存在,并依次回退到 cwd basename 和 Session id。冷启动的持久会话会保持该回退值,直到打开或恢复会话,促使主机折叠并投影日志支的标题。
`SessionManager` 独立于列表和 Session 实例到达情况,保留最近一次通过验证的 `session/title` 控制快照。seq 更的事件会替换旧快照,标题时间戳计入列表新近程度;订阅基线会先丢弃 seq 超过其 `lastSeq` 的任何已保留标题,再接收可选的折叠标题。显式移除 Session 也会清除已保留标题。因此,面向客户端的 `SessionSummary.title` 只包含实的持久标题;`displayTitle` 始终存在,并依次回退到 cwd basename 和 Session id。冷持久会话会保持该回退值,直到打开或恢复会话,促使主机折叠并投影日志支的标题。
## 会话模型选择
@@ -30,14 +30,14 @@ SlotsService 分别为 renderer 提供 `useSessions` 与 `useWorkspaces` 的裸
## 模型体验
无,因为 Session 对象层会选择后续 Host 请求使用的提供方/模型路由,但不添加任何模型可见内容。
无,因为会话对象层会选择后续 Host 请求使用的提供方/模型路由,但不添加任何模型可见内容。
#### KV Cache 影响
更改目标可能改变提供方侧的缓存复用,或使其失效;该包本身不会改变提示词前缀。
更改目标可能改变提供方侧的缓存复用,或使其失效;该包package本身不会改变提示词前缀。
## 已知限制与暂缓事项
- **`loader.unload` 是 stub抛出 not-implemented**完整链路fiber 释放 → 注册级联 → 样式移除)随 HMR 项目落地。
- **scope 拆卸由阶段驱动,目前只能有一个占用者**:已 staged 的 Session 精确跟随 `list.current`staging 就是打开信号:事件窗口打开 ⟺ Session 位于 stage在 staged 状态下被移除的 Session,其 scope 会冻结保留,直到 stage 转向其他 Session,而非直到真实观察者数量降为零。解析(`binding()``scope()`)只是纯寻址,可安全用于渲染;渲染层经 `currentProvideInfo` observable 读取当前 bundle。并发 pane 落地时staged 状态可以扩展为多 pane 列表。
- **插件组合包从该包执行值导入时必须使用 `/client` 子路径**:裸包名不在 loader external 表中,会内联第二个模块实例;其私有 scope-tag Symbol 永远无法匹配(空状态 P0 事故复盘)。
- **`loader.unload` 是 stub抛出 not-implemented**完整链路fiber dispose资源释放 → 注册级联 → 样式移除)随 HMR(热模块替换)项目落地。
- **scope 拆卸由阶段驱动,目前只能有一个占用者**:已 staged 的会话精确跟随 `list.current`staging 就是打开信号:事件窗口打开 ⟺ 会话位于 stage在 staged 状态下被移除的会话,其 scope 会冻结保留,直到 stage 转向其他会话,而非直到真实观察者数量降为零。解析(`binding()``scope()`)只是纯寻址,可安全用于渲染;渲染层经 `currentProvideInfo` observable 读取当前 bundle。并发 pane 落地时staged 状态可以扩展为多 pane 列表。
- **插件组合包从该包导入时必须使用 `/client` 子路径**:裸包名不在 loader externals 表中,会内联第二个模块实例;其私有 scope-tag Symbol 永远无法匹配(空状态 P0 事故复盘)。

View File

@@ -2,20 +2,20 @@
[English](README.md) | 中文
模型选择插件(浏览器侧):**两个入口共用一份 per-session 目录**,由 `ModelService``ctx.models`)持有。`/model` popupSelect contribution(经 `ctx.command` 注册)与 composer 的具名 `conversation.input.model` 坑位都通过同一个 `ModelDirectory` 实例,经 `session.models` 加载会话的建议目录,并经 `session.selectModel` 提交。紧凑型 composer 触发器会打开两级 Model/Effort 菜单:模型仍按提供方分组,所选确切模型则提供由其适配器持有的推理强度名称、说明和默认值。Host 报告的提供方模型推理reasoning目标是两个入口共同回显的唯一事实`/model` 应用所选模型的默认推理强度composer 随后可以选择任一已公布的推理强度。目录加载与选择共享一个代次计数器,旧响应不会覆盖新结果;连接重置会丢弃所有常驻目录投影,并在显示前重新拉取 Host 恢复的目标。提供方元数据失败会内联列出,同时可用分组仍可选择;选择失败会保留先前的目标和目录。目录按会话惰性解析(`ctx.models.directoryFor(sessionId)`),随会话 scope 一并释放。
模型选择插件(浏览器侧):**两个入口共用一份 会话级目录**,由 `ModelService``ctx.models`)持有。`/model` popupSelect 贡献项(经 `ctx.command` 注册)与 composer 的具名 `conversation.input.model` 坑位都通过同一个 `ModelDirectory` 实例,经 `session.models` 加载会话的建议目录,并经 `session.selectModel` 提交。紧凑型 composer 触发器会打开两级 Model/Effort 菜单:模型仍按提供方分组,所选具体模型则提供由其适配器持有的推理强度名称、说明和默认值。Host 报告的提供方模型推理reasoning目标是两个入口共同回显的唯一事实`/model` 应用所选模型的默认推理强度composer 随后可以选择任一已公布的推理强度。目录加载与选择共享一个代次计数器,旧响应不会覆盖新结果;连接重置会丢弃所有常驻目录投影,并在显示前重新拉取 Host 恢复的目标。提供方元数据获取失败会内联列出,同时可用分组仍可选择;选择失败会保留先前的目标和目录。目录按会话惰性解析(`ctx.models.directoryFor(sessionId)`),随会话作用域 一并释放。
`/client` 导出面为插件本体(`apply`/`inject`)、`ModelService``ModelDirectory` 及其状态形状、坑位注入面类型。
## Model Experience
## 模型体验
间接影响,经两个入口共同提交的 `session.selectModel` RPCHost 在下一次提示词组装边界快照所选提供方/模型/推理强度目标,因此后续请求采用所选路由和推理强度,而运行中的步骤保留已组装目标。只有当现有请求头记录一次实际采用该选择的请求后,选择才会持久化;菜单交互不会添加提示词内容。
间接影响,经两个入口共同提交的 `session.selectModel` RPCHost 在下一次提示词组装边界快照所选提供方/模型/推理强度目标,因此下一次请求采用所选路由和推理强度,而运行中的步骤保留已组装目标。只有当现有请求头记录一次实际采用该选择的请求后,选择才会持久化;菜单交互不会添加提示词内容。
#### KV Cache effect
#### KV Cache 影响
切换路由可能降低或作废提供方侧后续请求的缓存复用;提示词前缀本身不受影响。
切换路由可能减少提供方侧后续请求的缓存复用,或使其失效;提示词前缀本身不受影响。
## Known Limitations and Deferred Work
## 已知限制与暂缓事项
- **无创建期选择**——两个入口都寻址既有会话的 agent;没有 Draft 期模型选择入会话创建的通道host `targetFor` 的种子序注释记录了该层未来的落点)。
- **目录名仅供呈现**——选择与持久化使用提供方/模型/推理强度 id目录查询或确切模型元数据查询失败的提供方以不可选失败行列出,重新加载前保持原样。
- **不能任意输入推理强度**——composer 仅提供确切模型由适配器公布的推理强度;适配器没有推理元数据时不显示 Effort 行。
- **无创建期选择**——两个入口都面向既有会话的 agent(智能体);没有将草稿阶段的模型选择入会话创建的通道host `targetFor` 的种子顺序说明了该层未来的落点)。
- **目录名仅供呈现**——选择与持久化使用提供方/模型/推理强度 id目录查询或具体模型元数据查询失败的提供方以不可选失败行列出,重新加载前保持原样。
- **不能任意输入推理强度**——composer 仅提供具体模型由适配器公布的推理强度;适配器没有推理元数据时不显示 Effort 行。

View File

@@ -10,7 +10,7 @@
#### KV Cache 影响
无;该包既不组装也不发送提供方请求。
无;该包package既不组装也不发送提供方请求。
## 已知限制与暂缓事项

View File

@@ -6,11 +6,11 @@
## Markdown 渲染
`MarkdownText` 通过 React 元素渲染来自不受信任 assistant 输出的 GFM。它会省略原始 HTML使相对链接及非 HTTP(S)/mailto 链接失效,以安全的外部链接属性打开 HTTP(S) 链接,并只渲染图片 alt 文本而不加载远程资源;`MessageText` 仍是用户创作内容使用的字面文本原语。元素间距、表格、链接与行内代码使用与 deepsuite `@deepseek/md` 相同的 `--dsw-alias-markdown-*` / `--dsw-font-markdown-*` token。围栏代码块通过 `CodeBlock` 渲染(语言横幅、复制控件,以及对已注册语法使用 shiki
`MarkdownText` 通过 React 元素渲染来自不受信任 assistant 输出的 GFM。它会省略原始 HTML使相对链接及非 HTTP(S)/mailto 链接失效,以安全的外部链接属性打开 HTTP(S) 链接,并只渲染图片 alt 文本而不加载远程资源;`MessageText` 仍是用户创作内容使用的字面文本原语。元素间距、表格、链接与行内代码使用与 deepsuite `@deepseek/md` 相同的 `--dsw-alias-markdown-*` / `--dsw-font-markdown-*` token。围栏代码块通过 `CodeBlock` 渲染(语言横幅、复制控件,以及对已注册语法使用 shiki
## 模型体验
无。该包在浏览器中渲染纯 React 原子组件;这里没有任何内容进入模型请求。
无。该包package在浏览器中渲染纯 React 原子组件;这里没有任何内容进入模型请求。
#### KV Cache 影响
@@ -20,4 +20,4 @@
- **字形级图标是重新绘制的近似版本**:鱼形标志(以及 ui-conversation 持有的闪光图标)来自字体字形,而本地设计数据无法导出其矢量几何;在获得精确导出路径前,使用手工重建版本代替。
- **Pill 与 Input 没有设计来源**:两个原子组件均自行定义;与其相似的侧边栏搜索字段和视图标签条由消费方组合,不是这些原子组件。
- **StateDot 的 `Active` 变体是设计中的隐藏占位符**尚未实现已交付的四种状态done/warning/ongoing/error构成完整的 P-I 表层
- **StateDot 的 `Active` 变体是设计中的隐藏占位符**尚未实现已交付的四种状态done/warning/ongoing/error就是 P-I 阶段对外提供的全部状态

View File

@@ -10,7 +10,7 @@
#### KV Cache 影响
无;该包既不组装也不发送提供方请求。
无;该包package既不组装也不发送提供方请求。
## 已知限制与暂缓事项

View File

@@ -2,11 +2,11 @@
[English](README.md) | 中文
侧边栏插件:真实 Host Workspace 按稳定的 Host 顺序排列;每个 Workspace 按自身顺序包含其 `sessionIds`,并以 `parentId` 嵌套;不属于任何 Workspace 的 Session 显示在末尾的 `Ungrouped` 分区。搜索、状态点以及折叠到布局拥有的 56px 轨道,都只属于呈现层。契约:[slot 系统标准](../../../.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.md)。
侧边栏插件:真实 Host Workspace 按稳定的 Host 顺序排列;每个 Workspace 按自身顺序包含其 `sessionIds`,并以 `parentId` 嵌套;不属于任何 Workspace 的会话显示在末尾的 `Ungrouped` 分区。搜索、状态点以及折叠到布局拥有的 56px 轨道,都只属于呈现层。契约:[slot 系统标准](../../../.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.md)。
New Session 会启动运行时的页面局部前端 Session Intent真实 Workspace 的「+」会启动一项以该 Workspace 为目标的 Intent。Workspace 标题栏的「+」打开 ui-workspace 的共享选择器,选择结果同样以一个前端 Session 为目标。Workspace Intent 不会出现在侧边栏中。
New Session 会启动运行时的页面局部前端 Session Intent真实 Workspace 的「+」会启动一项以该 Workspace 为目标的 Intent。Workspace 标题栏的「+」打开 ui-workspace 的共享选择器,选择结果同样以一个前端会话为目标。Workspace Intent 不会出现在侧边栏中。
`SidebarRootComponentProps` 组合布局 owner share、全局 `useSessions``useWorkspaces` hook、已声明的 `sidebar.workspace``sidebar.settings` 子 slot以及注入的 `startSession``open` 和侧边栏切换回调。这里没有插件 store`deriveGroups` 消费对象层快照与组件局部的展开/搜索状态。
`SidebarRootComponentProps` 组合布局 owner share、全局 `useSessions``useWorkspaces` 钩子、已声明的 `sidebar.workspace``sidebar.settings` 子 slot以及注入的 `startSession``open` 和侧边栏切换回调。这里没有插件 store`deriveGroups` 消费对象层快照与组件局部的展开/搜索状态。
页脚承载 `sidebar.settings`:侧边栏只渲染固定在底部的布局 slot并共享其栏状态`wide`ui-settings 在此注册触发行和设置面板。
@@ -18,10 +18,10 @@ New Session 会启动运行时的页面局部前端 Session Intent真实 Work
#### KV Cache 影响
无;该包既不组装也不发送提供方请求。
无;该包package既不组装也不发送提供方请求。
## 已知限制与暂缓事项
- **状态点只有两种实时数据状态running/none**done/error/amber 数据源随 P-II 审批与通知到来;四色原语已经接线
- **状态点只有两种实时数据状态running/none**done/error/amber 数据源随 P-II 审批与通知功能一并提供;四色原语已接入
- **分组选单只提供按 Workspace 分组**Update/Status 分组策略只有图稿而没有规范,暂缓实现。
- **「New task completed」未读标记是本地查看状态**:完成时间 > 上次查看时间这一事实永远不会到达主
- **「New task completed」未读标记是本地查看状态**:完成时间 > 上次查看时间这一事实永远不会到达宿主。

View File

@@ -2,7 +2,7 @@
[English](README.md) | 中文
skill技能引用 source 的浏览器半侧:把 `/` 触发的 `skill` source 注册进 `ctx.slash`。候选来自 `skill.list` RPC以每次调用的 `ClientSessionContext` 投影中的 `{sessionId}` 寻址——每个会话恒为 agent-backedhost 从会话 header 解析 `cwd`。目录按会话缓存,拉取走 single-flightscope 出生`warm` 钩子预热该会话的缓存项,`connection/reset` 清空全部缓存。结果按 `startsWith(query)` 过滤pick 一个候选会把字面文本 `/name ` 经 slash 管线落进草稿(决策 21 的纯文本引用source 的 `codec` 拥有该引用的两种投影:`clipboardText``/name``serialize` → 提交时生成的模型形式 `<skill>name</skill>`。RPC 使用插件注册时捕获的根上下文连接——source 绝不从每次调用的参数上读取服务。source 不实现 `matchSpace``matchEnter` 钩子——skill 引用永不进入命令裁决,随普通提示词落入 default sink。
skill技能引用 source 的浏览器:把 `/` 触发的 `skill` source 注册进 `ctx.slash`。候选来自 `skill.list` RPC以每次调用的 `ClientSessionContext` 投影中的 `{sessionId}` 寻址——每个会话始终由 agent(智能体)支撑host 从会话 header 解析 `cwd`。目录按会话缓存,拉取走 single-flightscope 创建时`warm` 钩子预热该会话的缓存项,`connection/reset` 清空全部缓存。结果按 `startsWith(query)` 过滤pick 一个候选会把字面文本 `/name ` 经 slash 管线落进草稿(决策 21 的纯文本引用source 的 `codec` 拥有该引用的两种投影:`clipboardText``/name``serialize` → 提交时生成的模型形式 `<skill>name</skill>`。RPC 使用插件注册时捕获的根上下文连接——source 绝不从每次调用的参数上读取服务。source 不实现 `matchSpace``matchEnter` 钩子——skill 引用永不进入命令裁决,随普通提示词落入 default sink。
`skill.list` 失败时 `candidates` 抛出异常slash 壳层记录日志并折叠为静默的菜单组丢弃——菜单只显示 pendingready 状态。
@@ -18,14 +18,14 @@ skill技能引用 source 的浏览器半侧:把 `/` 触发的 `skill` so
#### Token 影响
有条件且极小:只有 pick或手动键入相同文本会把引用的字符加进那一条用户消息。浏览菜单和候选拉取增加零模型 token。
有条件且极小:只有 pick或手动键入相同文本会把引用的字符加进那一条用户消息。浏览菜单和拉取候选不会增加任何模型 token。
#### KV Cache 影响
仅追加:引用是追加在可复用历史前缀之后的新用户消息的一部分。该包绝不改写较早的请求 token。
仅追加:引用是追加在可复用历史前缀之后的新用户消息的一部分。该包package绝不改写较早的请求 token。
## 已知限制与暂缓事项
- **skill 加载不确定**:引用是协作线索,不是保证;模型可能忽略它。命中率被证明不足时的返工路径host 侧 `context/skill-reference` 引导包,或全文注入)记录在设计台账中;wire 上的文本形不会改变。
- **首次击键可能与预热竞速**scope 出生的预热会启动目录拉取,但目录落定之前打开的菜单,在那次击键下不会显示 skill 候选。这是设计上接受的取舍skill 引用不参与回车裁决,因此没有任何攸关正确性的环节等待目录。
- **文本即真身**:引用是普通的草稿文本;手动键入的相同 token 就是同一个引用。chip 视觉由 lexicon 扫描派生;没有 occurrence 身份或位置跟踪(组件化 chip 是台账事项)。
- **skill 加载不确定**:引用是协作线索,不是保证;模型可能忽略它。针对命中率不足情况的返工路径host 侧 `context/skill-reference` 引导包,或全文注入)记录在设计台账中;协议中的文本形不会改变。
- **首次击键可能与预热竞速**scope 创建时的预热会启动目录拉取,但目录落定之前打开的菜单,在那次击键下不会显示 skill 候选。这是设计上接受的取舍skill 引用不参与回车裁决,因此没有任何攸关正确性的环节等待目录。
- **文本是唯一依据**:引用是普通的草稿文本;手动键入的相同 token 就是同一个引用。chip 视觉由 lexicon 扫描派生;没有 occurrence 身份或位置跟踪(组件化 chip 是台账事项)。

View File

@@ -2,25 +2,25 @@
[English](README.md) | 中文
输入触发线插件:光标处的 `/``@` 检测(词边界 + guard tier 规则)、分组候选菜单,以及把 pick 路由到已注册 source。`ctx.slash` 拥有 source roster并按会话 scope`sessionOf`)各解析一个 `SlashController`会话领域的接线层在 controller 上驱动 `track``arbitrate``onSpace``adjudicate`。source 每次调用收到一个 `ClientSessionContext` 投影——会话恒为 agent-backed因此投影只含会话身份。source 在它能触达的每个会话 controller 中都会被预热scope 出生时在场的 roster 随 controller 构造预热,晚于此注册的 source 由注册动作本身预热进每个活 controller。`lexicon` 名录在预热后仍会变化的 source 实现 `subscribeLexicon(session, listener)`controller 每收到通知就重拉,并把聚合结果经其 `lexicon` snapshot store 发布。管线对命令零知识:空格/回车裁决按注册序轮询可选的 `matchSpace``matchEnter` 钩子,第一个非 undefined 的应答胜出。
输入触发流水线插件:光标处的 `/``@` 检测(词边界 + guard tier 规则)、分组候选菜单,以及把 pick 路由到已注册 source。`ctx.slash` 拥有 source roster并按会话 scope`sessionOf`)各解析一个 `SlashController`对话接线层在 controller 上驱动 `track``arbitrate``onSpace``adjudicate`。source 每次调用收到一个 `ClientSessionContext` 投影——会话始终由 agent(智能体)支撑因此投影只含会话身份。source 在它能触达的每个会话 controller 中都会被预热scope 出生时在场的 roster 随 controller 构造预热,晚于此注册的 source 由注册动作本身预热进每个活 controller。`lexicon` 名录在预热后仍会变化的 source 实现 `subscribeLexicon(session, listener)`controller 每收到通知就重拉,并把聚合结果经其 `lexicon` 快照 store 发布。流水线与命令无关:空格/回车裁决按注册序轮询可选的 `matchSpace``matchEnter` 钩子,第一个非 undefined 的应答胜出。
分层:`src/core/`T2是纯内核——`detectTrigger``menuReduce``seedGroups``MENU_CLOSED``exactMatch`,零 ReactDOMcordis`src/client/service.ts` 是壳层,把内核接到菜单快照 store、逐 hit 候选拉取(以 generation 把关、后继请求经 `AbortSignal` 取代旧请求、失败的 source 静默丢弃并留一条 console 记录)和三条 pick 路径上。`src/types.ts` 与两个 `contract.ts` 文件是冻结的跨包契约(设计 v4 §5.1);变更需经主线程仲裁。
MenuView 把菜单 store 渲染进 `conversation.input.overlay` slot列表类会话 scope菜单关闭期间渲染 null。该 slot 由 ui-conversation 的编辑器配置项拥有锚点、children 声明、生命周期);其 SlotMap 类型合并放在本包的 `src/client/slots.ts`因为依赖方向ui-conversation → ui-slash不允许反向的类型导入。combobox 模式:焦点始终留在 textarea行在 mousedown 时完成 pick高亮由 `aria-activedescendant` 承载。
MenuView 把菜单 store 渲染进 `conversation.input.overlay` slot列表类会话 scope菜单关闭期间渲染 null。该 slot 由 ui-conversation 的组合器条目拥有锚点、children 声明、生命周期);其 SlotMap 类型合并放在本包的 `src/client/slots.ts`因为依赖方向ui-conversation → ui-slash不允许反向的类型导入。combobox 模式:焦点始终留在 textarea行在 mousedown 时完成 pick高亮由 `aria-activedescendant` 承载。
`/client` 导出表层是插件主体(`apply``inject`)、`SlashService``MenuViewInjected` 与契约类型。MenuView 本身是内部实现——slot 注册以闭包持有它。
## 模型体验
无。触发线只是浏览器呈现——pick 产出 `CommandClaim``ReferenceInsert` 数据,其模型可见后果(host 命令执行;插入的引用文本随普通提示词发送)由消费方的 host 包与输入状态机包拥有。
无。触发流水线只是浏览器呈现——pick 产出 `CommandClaim``ReferenceInsert` 数据,其模型可见后果(宿主命令执行;插入的引用文本随普通提示词发送)由消费方的 host 包与输入状态机包拥有。
#### KV Cache 影响
无;该包既不组装也不发送提供方请求。
无;该包package既不组装也不发送提供方请求。
## 已知限制与暂缓事项
- **只有全局 source 层**:会话 scope 的 source 注册(逐会话遮蔽、类 ScopedLayers 机制)已有设计但未启用;台账记录着触发条件(出现真实的逐会话 source 需求)。
- **`SlashCandidate.icon` 以文本渲染**MenuView 把该字符串原样放进图标位;接到设计系统图标枚举iconFile 五变体家族)的接线等该枚举交付后落地
- **`SlashCandidate.icon` 以文本渲染**MenuView 把该字符串原样放进图标位;设计系统图标枚举iconFile 五变体家族)的接入将在该枚举交付后完成
- **overlay 的 SlotMap 合并归属与 slot 所有权分离**`conversation.input.overlay` 的合并放在本包(唯一副本),而该 slot 的 owner 语义锚点、children 声明、生命周期)留在 ui-conversation依赖方向ui-conversation → ui-slash迫使这一拆分未来依赖关系调整时应重新审视。
- **菜单组顺序即注册顺序**source 之间没有显式排序 seamroster 还是 commandskillsubagent 时可以接受,业务 source 加入后需重新审视。
- **菜单组顺序即注册顺序**source 之间没有显式排序 seamroster 还是 commandskill(技能)subagent 时可以接受,业务 source 加入后需重新审视。

View File

@@ -2,24 +2,24 @@
[English](README.md) | 中文
Slot 注册表纯核心、slot 终端设计SlotMap 声明合并、SlotCore 上唯一的 `register` 组合 API、四 share 组件 props 类型家族、store seat 类型家族,以及 renderer 安装 seam 契约。React 类型仅在运行时使用,该包不依赖 React也不依赖 cordis。
Slot 注册表纯核心、slot 终端设计SlotMap 声明合并、SlotCore 上唯一的 `register` 组合 API、四 share 组件 props 类型家族、store seat 类型家族,以及 renderer 安装 seam 契约。只使用 React 类型该包package不依赖 React也不依赖 Cordis。
一次 `register({ name, children?, store?, inject?, ...kind }, Component)` 调用会向已声明 slot 贡献一个组件,同时声明子 slot声明 = 渲染授权 = 运行时规范三者共用一张表、store seat 以及注册方的业务表层。组件会在调用点依据 `ComposedProps` 接受检查;该类型是四个 share 的交集,每个 share 都从各自的唯一真源派生:
| share | 类型 | 来源 |
|---|---|---|
| runtime | `PropsRuntime<K>` | SlotMap 配置项`owner`(父级 renderSlot 调用点)+ Session 标准工具包 + 全局 seat |
| runtime | `PropsRuntime<K>` | SlotMap 条目`owner`(父级 renderSlot 调用点)+ Session 标准工具包 + 全局 seat |
| child render | `PropsRenderSlots<S>` | register 调用的 `children` key 集合(静态缩窄的 `renderSlot` |
| store | `PropsStore<H>` | 已声明 handle`useStore` selector hook + 移除 draft 的 `actions` |
| business | `I` | 从 `inject` factory 返回值推断 |
chain-kind slot 会反转键控路由:配置项自行提名,而不是由分发点选择 `entryKey`。每次注册都携带一个纯 `ChainSelect` selector另有可选的升序 `priority`,相同值按注册顺序处理);第一个非 null 返回值选中其配置项,并成为组件的 `matched` prop全部返回 null 时则使用 owner 的 `renderSlotChain` fallback`ChainRenderOpts`)。
chain-kind slot 会反转键控路由:条目自行提名,而不是由分发点选择 `entryKey`。每次注册都携带一个纯 `ChainSelect` selector另有可选的升序 `priority`,相同值按注册顺序处理);第一个非 null 返回值选中其条目,并成为组件的 `matched` prop全部返回 null 时则使用 owner 的 `renderSlotChain` fallback`ChainRenderOpts`)。
标准工具包接口(`SessionStandardProps``GlobalStandardProps`)在这里声明为空,由 runtime 包合并(与 SlotMap key 相同的 declare-merge 模式。renderer 会把运行时 Session 和 Workspace observable source 绑定为 selector hook。Inject factory 参数从声明派生(`InjectParams`Session slot 获得 `sessionId`;声明 store 时追加 baked `actions`;没有其他参数,数据访问位于 apply 闭包的 ctx 中。
store 家族(输入 `defineStore` 规范/输出 `StoreHandle<T, A>`)为 store seat 建模:`init` 推断状态 schema`actions` 是完整的 draft-transform 写入集合;`BakedActions` 移除 draft 参数,成为组件和 inject factory 收到的回调。`defineStore` 值实现位于 runtime 包(引擎所属位置),并满足这里导出的 `DefineStore` 契约。引擎产物与 renderer host 契约携带裸快照 source`getSnapshot``subscribe`),绝不携带 React hookhook 绑定属于渲染机制这一侧的 seam只有 props 契约 hook 类型(`SnapshotSelectorHook`)位于这里。
`SlotCore` 在构造时播种先验的 `'root'` slot并强制执行加载时验证注册未声明 slot、重复声明子项、在两个 scope 下使用同一个共享 handle、chain 注册缺少 `select`,这些情况都在 register 时抛出)。配置项的 disposer 会递归折叠其声明的子 slot账本行、贡献和 store 挂载都沿同一生命周期轴消失`renderer.ts` 携带安装 seam`SlotRenderer``SlotRendererHost`)以及 `StaleAuthorizationError``SlotOwnershipError`;实现在 web-react 中,安装则在外壳启动中完成。
`SlotCore` 在构造时预置 `'root'` slot并强制执行加载时验证注册未声明 slot、重复声明子项、在两个 scope 下使用同一个共享 handle、chain 注册缺少 `select`,这些情况都在 register 时抛出)。条目的 disposer 会递归移除其声明的子 slot账本行、贡献和 store 挂载都会随同一生命周期结束而移除`renderer.ts` 携带安装 seam`SlotRenderer``SlotRendererHost`)以及 `StaleAuthorizationError``SlotOwnershipError`;实现在 web-react 中,安装则在外壳启动中完成。
## 模型体验
@@ -31,5 +31,5 @@ store 家族(输入 `defineStore` 规范/输出 `StoreHandle<T, A>`)为 st
## 已知限制与暂缓事项
- **`isLive` 会线性扫描所有记录**:在 UI 插件的注册规模(数十项)下没有问题;如果账本变得频繁访问,再使用配置项→记录反向引用改进。
- **`isLive` 会线性扫描所有记录**:在 UI 插件的注册规模(数十项)下没有问题;如果账本变得频繁访问,再使用条目→记录反向引用改进。
- **`__renders` 幻象锚点在 `PropsRenderSlots` 上可见**:这是与类型链设计的 `__accepts` 相同且已接受的噪声;泛型方法签名在 key 联合之间比较宽松,因此必须依靠逆变标记强制执行「组件 key 集合 ⊆ children 声明」。

View File

@@ -4,9 +4,9 @@
subagent 引用 source 的浏览器半侧:把 `@` 触发的 `subagent` source 注册进 `ctx.slash`。候选零 RPC——从注册时捕获的根 `ctx.sessions.list` 快照过滤(每次调用的投影所指会话的子会话:`parentId` 匹配、`running``displayTitle` 包含 querypick 一个候选会把字面文本 `@label ` 经 slash 管线落进草稿(决策 21 的纯文本引用source 的 `codec` 把两种投影都产出为 `@label`——在 `@` 消费功能定义模型表示之前,模型序列化保持原始 label。source 不实现 `matchSpace``matchEnter` 钩子——subagent 引用永不进入命令裁决,随普通提示词落入 default sink。
没有运行中子会话的会话就是没有候选。本阶段只交付「菜单 + 引用文本」;消费一个 `@label` 意味着什么(对子会话做 steering中途引导、恢复已 dispose 的子会话)是未来的业务工作。
没有运行中子会话的会话就是没有候选。本阶段只交付「菜单 + 引用文本」;消费一个 `@label` 意味着什么(对子会话做 steering中途引导、恢复已 dispose(资源释放)的子会话)是未来的业务工作。
`/client` 导出表层只有插件主体(`apply``inject`source 对象是注册 effect 的内部实现。
`/client` 导出内容只有插件主体(`apply``inject`source 对象是注册 effect 的内部实现。
## 模型体验
@@ -26,6 +26,6 @@ subagent 引用 source 的浏览器半侧:把 `@` 触发的 `subagent` source
## 已知限制与暂缓事项
- **`@` 消费语义尚未构建**:引用只是惰性文本;把它接到对指名子会话 steering发消息以及是否允许恢复已 dispose 的子会话),待台账中它自己的设计决策。
- **候选只有运行中的子会话**:已完成或已 dispose 的 subagent 永不出现roster 只含 scope 所指会话的直接子会话(不含孙辈,不含跨会话 agent
- **label 是显示标题,不是稳定 id**:两个子会话共用一个显示标题时,产生的引用无法区分;标题变更会使先前插入的文本失去指向。引用还是惰性文本时可接受;消费功能必须绑定到会话 id。
- **`@` 消费语义尚未构建**:引用只是不具消费语义的纯文本;将其接入对指名子会话进行 steering消息的机制(以及是否允许恢复已 dispose 的子会话),仍有待台账中的专门设计决策。
- **候选只有运行中的子会话**:已完成或已 dispose 的 subagent 永不出现roster 只含 scope 所指会话的直接子会话(不含孙辈,不含跨会话 agent(智能体))。
- **label 是显示标题,不是稳定 id**:两个子会话共用一个显示标题时,产生的引用无法区分;标题变更会使先前插入的文本失去指向。引用仍是不具消费语义的纯文本时可接受;消费功能必须绑定到会话 id。

View File

@@ -6,9 +6,9 @@
`src/styles/` 下有五张样式表,全部由 web 壳的 `base.css` 导入:`base.css``design-platform.css``scrollbar.css``gradient-shadow-text.css``shiki.css``scrollbar.css``--dsw-alias-scrollbar-*` token 的唯一消费方,必须排在声明这些 token 的 `design-platform.css` 之后。
滚动条重新绑定契约:`scrollbar.css``body` 上把 `--dsh-scrollbar-thumb``--dsh-scrollbar-thumb-hover` 绑定到 l1基础表面token两条渲染路径都读取这一组变量。抬升表面(菜单、浮层、对话框)在自己的容器上设置 `--dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2)``--dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2)`;一次重新绑定即可为引擎实际走的那条路径换色。
滚动条重新绑定契约:`scrollbar.css``body` 上把 `--dsh-scrollbar-thumb``--dsh-scrollbar-thumb-hover` 绑定到 l1基础表面token两条渲染路径都读取这一组变量。高层级表面(菜单、浮层、对话框)在自己的容器上设置 `--dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2)``--dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2)`;一次重新绑定即可为引擎实际走的那条路径换色。
两条路径在构造上互斥。`scrollbar-width``scrollbar-color` 写在 `@supports not selector(::-webkit-scrollbar)` 之内,因为这两个属性只要取非 `auto`Chromium 与 Safari 就会丢弃该元素上的全部 `::-webkit-scrollbar*` 规则,`::-webkit-scrollbar-thumb:hover` 也在其中——若无条件地同时声明,`--dsh-scrollbar-thumb-hover` 在任何引擎上都不会被渲染。因此 Firefox 走标准属性WebKit 系引擎走伪元素hover token 只经由伪元素这条路径渲染。推理过程与实测计算值见[滚动条 Agent Note](../../../.agents/notes/implemented/bug-fix/2026-07-28-themed-scrollbars-and-reserved-gutter.md)。
两条路径在构造上互斥。`scrollbar-width``scrollbar-color` 写在 `@supports not selector(::-webkit-scrollbar)` 之内,因为这两个属性中的任一个只要取非 `auto`Chromium 与 Safari 就会丢弃该元素上的全部 `::-webkit-scrollbar*` 规则,`::-webkit-scrollbar-thumb:hover` 也在其中——若无条件地同时声明,`--dsh-scrollbar-thumb-hover` 在任何引擎上都不会被渲染。因此 Firefox 走标准属性WebKit 系引擎走伪元素hover token 只经由伪元素这条路径渲染。推理过程与实测计算值见[滚动条 Agent Noteagent 决策记录)](../../../.agents/notes/implemented/bug-fix/2026-07-28-themed-scrollbars-and-reserved-gutter.md)。
## 模型体验
@@ -16,9 +16,9 @@
#### KV Cache 影响
无;该包既不组装也不发送提供方请求。
无;该包package既不组装也不发送提供方请求。
## 已知限制与暂缓事项
- **第三方主题是表层,不是产品**:注册主题意味着覆盖同名别名变量;目前不会验证一组覆盖是否完整。
- **token 样式表是颜色的唯一权威**不会追加 cssdesign 中缺失的值(例如设计中的 #4176E6 标签页蓝色);应使用最接近的语义 token裁定于 2026-07-22
- **token 样式表是颜色的唯一权威来源**会有意不补入 cssdesign 中缺失的值(例如设计中的 #4176E6 标签页蓝色);一律采用最接近的语义 token裁定于 2026-07-22

View File

@@ -2,7 +2,7 @@
[English](README.md) | 中文
轨迹轮次列表 chrome(吸顶 TurnMessage·Step 分组/步骤单元格)及 Waterfall 占位符;这是纯消费方最小插件范例(向会话的 `'conversation.view'` slot 环注册两个视图标签页,不提供服务,也不声明 Context 合并。契约api-contracts v3 §8。
轨迹轮次列表界面框架(吸顶 TurnMessage·Step 分组/步骤单元格)及 Waterfall(瀑布式事件)占位符;这是纯消费方最小插件范例(向会话的 `'conversation.view'` slot 环注册两个视图标签页,不提供服务,也不声明 Context 合并。契约api-contracts v3 §8。
## 模型体验
@@ -10,8 +10,8 @@
#### KV Cache 影响
无;该包既不组装也不发送提供方请求。
无;该包package既不组装也不发送提供方请求。
## 已知限制与暂缓事项
- **进行中Time 保持空白**`partial``runningCalls` 行在实时钟策略落地前渲染为 `—`;选中样式只在本地生效(未连接到聊天详情);锚点深链接仍暂缓实现。
- **进行中时,Time 保持空白**`partial``runningCalls` 行在实时钟策略落地前渲染为 `—`;选中样式仅在当前视图内部生效(未连接到聊天详情);锚点深链接仍暂缓实现。

View File

@@ -2,7 +2,7 @@
[English](README.md) | 中文
slot 终端设计的外壳侧 React 胶水createSlotRenderer外壳安装到运行时 SlotsService 的 SlotRenderer 实现、SessionProvider框架接线的 render prop也作为标准 seat 注入到声明会话 scope 子的配置项、bindSnapshotSelector唯一的 hook 构造器:主机与引擎只传递裸 observable source每个 hook 在此绑定,并按 source 缓存、useInvoke。链式 slot outlet 在渲染时按链顺序运行已注册 selector只挂载被选中的配置项其 select 返回值以 `matched` 加入 props`renderSlotChain` binding`renderSlot` 一样按配置项缓存。快照 store 引擎与 defineStore 位于 runtimestore 已迁移);业务插件只依赖 ui-slots 类型,绝不依赖该包。
slot 终端设计的外壳侧 React 胶水createSlotRenderer外壳安装到运行时 SlotsService 的 SlotRenderer 实现、SessionProvider框架接的 render prop也作为标准 seat 注入到声明会话 scope 子 slot 的配置项、bindSnapshotSelector唯一的 钩子 构造器:主机与引擎只传递裸 observable source每个 钩子 在此绑定,并按 source 缓存、useInvoke。链式 slot outlet 在渲染时按链顺序运行已注册 selector只挂载被选中的配置项其 select 返回值以 `matched` 加入 props`renderSlotChain` 绑定`renderSlot` 一样按配置项缓存。快照 store 引擎与 defineStore 位于运行时store 已迁移);业务插件只依赖 ui-slots 类型,绝不依赖该包package
## 模型体验
@@ -14,6 +14,6 @@ slot 终端设计的外壳侧 React 胶水createSlotRenderer外壳安装
## 已知限制与暂缓事项
- **persist 中间件会损坏原始值状态 store**:保存时它会对状态执行对象展开,因此 `SnapshotStore<string>` 往返后会变成字符 map;引擎改为自行实现持久化(见 `attachPersistence`)。
- **persist 中间件会损坏原始值状态 store**:保存时它会对状态执行对象展开,因此 `SnapshotStore<string>` 往返后会变成字符映射;引擎改为自行实现持久化(见 `attachPersistence`)。
- **`UseSession` 有意保持宽泛(`object` 快照)**依赖方向runtime → web-react绝不反向使真实 `ConversationSnapshot` 类型不可访问;会话 slot 消费方在其边界处缩窄一次。
- **renderSlot 是唯一的 P-I 形式**:没有 Suspense也没有逐配置项惰性加载渐进式渲染表层会随其独立项目回归
- **renderSlot 是唯一的 P-I 形式**:没有 Suspense也没有逐配置项惰性加载渐进式渲染能力将在其独立项目中恢复

View File

@@ -2,19 +2,19 @@
[English](README.md) | 中文
Web 外壳内核:`new AppWebEntry(el, seams?).run()` 通过两阶段启动web2挂载整个客户端。第一阶段模块表层):构建客户端模块系统(`@deepseek-ai/dsh-client-modules`),以主机推送的配置项图(`window.__DSH_BOOT__`)为基础,并行预`immediately` 层级;执行组合包只会注册 factory。第二阶段插件表层):挂载 vendored cordis Loader并把模块系统作为其 `internal` seam 注入;为每一行图数据创建一个 loader 配置项,另创建外壳自身的 app-shell 组装配置项tree.import 会物化各模块);以 settle 作为 AppRoot 的门禁loader 完全停稳 + 每个配置项 fiber 都为 ACTIVE → 一次切换显示完整 UI。组合完全由主机图决定花名册和 immediately 层级都位于负责组合的应用中;外壳不作任何组合决策。
Web 外壳内核:`new AppWebEntry(el, seams?).run()` 通过两阶段启动web2挂载整个客户端。第一阶段模块):构建客户端模块系统(`@deepseek-ai/dsh-client-modules`),以主机推送的配置项图(`window.__DSH_BOOT__`)为基础,并行预取 `immediately` 层级;执行组合包只会注册 factory。第二阶段插件):挂载 仓库内置的 Cordis Loader并把模块系统作为其 `internal` seam 注入;为每一行图数据创建一个 loader 配置项,另创建外壳自身的 app-shell 组装配置项tree.import 会物化各模块);以 settle 作为 AppRoot 的门禁loader 完全停稳 + 每个配置项 fiber 都为 ACTIVE → 一次切换显示完整 UI。组合完全由主机图决定花名册和 immediately 层级都位于负责组合的应用中;外壳不作任何组合决策。
外壳自给自足web2 硬性规则):内核不对任何插件包执行值导入;启动状态 store 与信号在这里手写(`loader-status.ts`),因此插件失败时(尤其在失败时)加载页面仍能工作。app-shell 组装(`@deepseek-ai/dsh-client-app-shell`,由外壳拥有、背后没有 npm 包的伪配置项)是唯一通过 `registerStatic` 注册的模块;它与任何插件一样,通过 inject 等待 slots/sessions/layout。
外壳自给自足web2 硬性规则):内核不对任何插件包package执行值导入;启动状态 store 与信号在这里手写(`loader-status.ts`),因此即使插件失败,加载页面仍能工作,而此时这一点尤其重要。app-shell 组装(`@deepseek-ai/dsh-client-app-shell`,由外壳拥有、背后没有 npm 包的伪配置项)是唯一通过 `registerStatic` 注册的模块;它与任何插件一样,通过 inject 等待 slots/sessions/layout。
`PLATFORM_MODULES`src/platform.ts是共享模块表层的唯一真源种子表 key、tsdown 客户端 external 和 vite alias 集都是它的投影。
可选 `seams` 参数会转发模块系统的 `fetchBundle``executeBundle` 传输覆盖(`BootSeams`);生产调用方省略此参数。它用于测试环境,因为此类环境中的 `<script>` 执行无法到达页面上下文jsdom
可选 `seams` 参数会转发模块系统的 `fetchBundle``executeBundle` 传输覆盖(`BootSeams`);生产调用方省略此参数。它用于 `<script>` 执行无法到达页面上下文的测试环境jsdom
外壳拥有浏览器标题投影。选中带有持久标题的会话时,它会渲染 `<session title> — <existing HTML title>` 并响应后续标题修订;未选择会话或选中无标题会话时,会保留现有标题;外壳卸载时恢复标题。现有 HTML 标题仍是可配置的产品后缀。
## 模型体验
无。配置项外壳负责启动浏览器插件树;这里没有任何内容进入模型请求。
无。入口外壳负责启动浏览器插件树;这里没有任何内容进入模型请求。
#### KV Cache 影响
@@ -22,5 +22,5 @@ Web 外壳内核:`new AppWebEntry(el, seams?).run()` 通过两阶段启动w
## 已知限制与暂缓事项
- **有意采用一次性渲染**UI 等待启动 settle只要一个配置项失败加载页面就会保留并高声逐项报告,不提供部分可用性(渐进式渲染会随其独立项目回归)。
- **有意采用一次性渲染**UI 等待启动 settle只要一个配置项失败加载页面就会保留并逐项显示醒目的报告,不提供部分可用性(渐进式渲染将作为独立项目恢复)。
- **窄窗口验收暂缓**ui-layout 已实现让步链,但外壳级窄视口演练是 P-II 验收项。

View File

@@ -2,11 +2,11 @@
[English](README.md) | 中文
代码执行能力 seam参见[能力 seam](../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md)):一个抽象运行时接口,用于针对宿主提供的异步绑定执行一段模型编写的程序,并捕获程序打印和返回的内容。消费方是工具注册表的 [Code Mode](../core/tools/README.md)`tools: { mode: code }`,即 `run_code` 工具与生成的 TypeScript SDK设计记录在 [Code Mode Agent Note](../../.agents/notes/implemented/feature/2026-06-15-code-mode.md) 中。这些都是**产品** 包。
代码执行能力 seam参见[能力 seam](../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md)):一个抽象运行时接口,用于针对宿主提供的异步绑定执行一段模型编写的程序,并捕获程序打印和返回的内容。消费方是工具注册表的 [Code Mode](../core/tools/README.md)`tools: { mode: code }`,即 `run_code` 工具与生成的 TypeScript SDK设计记录在 [Code Mode Agent Noteagent 决策记录)](../../.agents/notes/implemented/feature/2026-06-15-code-mode.md) 中。这些都是**产品**包package
| 包 | 职责 | ctx 键 |
|---|---|---|
| `code-runtime/` | 抽象代码执行 seam接口 + 词汇) | `ctx.codeRuntime` |
| [`code-runtime-worker/`](code-runtime-worker/README.md) | worker 线程后端:每次运行使用全新 worker由宿主侧剥离 TypeScript 类型(类型注解仅供参考,绝不执行类型检查)、端口桥接绑定、预算/堆隔离 | 注册 `ctx.codeRuntime` |
| [`code-runtime-worker/`](code-runtime-worker/README.md) | worker 线程后端:每次运行使用全新 worker由宿主侧剥离 TypeScript 类型(类型注解仅供参考,绝不执行类型检查)、端口桥接绑定、预算/堆限制 | 注册 `ctx.codeRuntime` |
接口位于 `code-runtime/code-runtime/`,随附后端位于 `code-runtime/code-runtime-worker/`。不同后端可以采用不同执行基底worker 线程、进程、容器)与源语言;二者都是服务上的只读描述符。后端注册 `ctx.codeRuntime`,无需修改接口或消费方;正是这种拆分,使未来可以直接换入强化后端。
接口位于 `code-runtime/code-runtime/`,随附后端位于 `code-runtime/code-runtime-worker/`。不同后端可以采用不同执行基底worker 线程、进程、容器)与源语言;二者都是服务上的只读描述符。后端注册 `ctx.codeRuntime`,无需修改接口或消费方;正是这种拆分,使未来可以直接换入加固后端。

View File

@@ -2,7 +2,7 @@
[English](README.md) | 中文
这是 [`@deepseek-ai/dsh-code-runtime`](../code-runtime/README.md) seam 的 worker 线程实现:`WorkerCodeRuntime` 会在每次运行中使用一个全新的 Node `worker_threads.Worker`,输入 TypeScript由宿主侧剥离类型通过消息端口桥接绑定输出 `{ value, logs, error? }`。**这是隔离措施,而非安全边界**:其信任立场有意与 bash 等价(参见 [Code Mode Agent Note](../../../.agents/notes/implemented/feature/2026-06-15-code-mode.md) 的 Trust posture 章节),但提供 bash 没有的隔离:独立 isolate、空环境、堆上限与强制终止。
这是 [`@deepseek-ai/dsh-code-runtime`](../code-runtime/README.md) seam 的 worker 线程实现:`WorkerCodeRuntime` 会在每次运行中使用一个全新的 Node `worker_threads.Worker`,输入 TypeScript由宿主侧剥离类型通过消息端口桥接绑定输出 `{ value, logs, error? }`。**这是隔离措施,而非安全边界**:其信任立场有意与 bash 等价(参见 [Code Mode Agent Noteagent 决策记录)](../../../.agents/notes/implemented/feature/2026-06-15-code-mode.md) 的 Trust posture 章节),但提供 bash 没有的隔离:独立 isolate、空环境、堆上限与强制终止。
## 配置
@@ -23,18 +23,18 @@
- **每次运行使用一个全新 worker不设池化**:程序所在的世界会随 worker 一同终止,不会留下需要记录的跨运行状态,也无法发生状态泄漏;仅凭会话日志即可重建运行。
- **在执行上下文中,由宿主侧剥离类型**:程序会包裹在异步函数外壳中,通过 `node:module``stripTypeScriptTypes` 剥离类型(只支持可擦除语法;`enum`namespace 会作为程序 `exception` 被拒绝,且不会启动 worker再按字节位置切回原内容。之后程序作为 `AsyncFunction` 的函数体执行,因此顶层 `await``return` 可用。
- **端口把对端视为不可信**:模型代码能够访问 `parentPort` 并伪造通信,因此任何代码读取入站消息前,系统都会验证其形状并重新构建(`null`、原始值、无效类型和格式错误的载荷会被静默丢弃;伪造的额外字段绝不会被带入);宿主对每个调用 id 最多响应一次,只将绑定名称解析为自有属性(伪造的 `constructor` 无法沿原型链访问),丢弃结算后的回复,并验证每个绑定 resolve 值与完成值是否为无损 JSON。伪造的 `log``done` 消息无法绕过外层上限宿主会再次验证并统计每条获准日志以及完成值或诊断。worker 侧命名空间使用 null-prototype 和 `defineProperty`,因此形似 `__proto__` 的绑定名称只是普通键。
- **绑定 reject 类属于请求数据**可选命名空间描述符会指定构造器全局变量以及用于接收失败成员名称的自有属性。worker 会创建并注入该真实类,使 `instanceof` 生效,同时无需硬编码 `tools``ToolCallError`;全局变量无效或冲突的声明会在启动 worker 前失败。失败路径使用模块捕获的错误与属性定义 intrinsic以及 null-prototype 描述符,因此模型之后的修改无法把被拒绝的绑定变成 worker 崩溃。
- **两个独立预算,因为对端不可信**`computeMs` 统计 worker 实际测得的忙碌时间(轮询 `worker.performance.eventLoopUtilization()`);热循环无法借助待完成的诱饵 dispatch 隐藏,程序等待慢工具时则不累计。`maxWallMs` 为忙碌时间无法观测的情况兜底(例如等待永远不会 resolve 的 promise。二者最终都会调用 `worker.terminate()`,连同步热循环也能终止;堆溢出会表现为 worker 的 OOM 退出(`kind: 'worker-exit'`)。`maxWallMs` 在加载时会对照 `MAX_TIMER_DELAY_MS` 做范围校验:`setTimeout` 会把更长的延迟夹到 1 ms仅有正数校验会放行一个在第一个 tick 就到期的上限。`computeMs` 不需要这道上界,因为它对照的是实测占用率,而不是喂给定时器。
- **中间绑定值是完整 JSON**:绑定参数与 resolve 值会接受迭代式无损 JSON 验证。程序执行前worker 会捕获自己 realm 中的普通容器原型身份,以及只用于外部 realm 的原生函数源码检查,因此构造器槽修改和用户编写的仿冒对象都无法改变容器分类。它还会捕获该 JSON 边界使用的每一个结构与计量 intrinsic以无原型对象创建属性描述符并绕过可变集合原型管理私有遍历状态因此模型对全局对象、原型方法或 `Object.prototype` 上形似描述符字段的修改都无法改变验证、wire 传输或字节计量。值会展平为有深度上限的前序 wire 值,供 structured clone 使用并在另一侧迭代式重建。它们没有字节、JavaScript 调用栈或嵌套 structured-clone 深度上限绝不会进入外层输出账本或模型上下文上限仍来自提供方执行器获取限制与进程worker 内存。
- **日志主动流入一个外层账本**consolestdoutstderr 文本按发送顺序穿过端口因此超时或被终止的程序仍会显示已经打印的内容。worker 会 JSON 字符串精确计费,并在发送完成值和异常诊断前,根据组合预算的剩余量预检;因此,抛出的百万字节 stack 会在 worker 边界变成固定的 `output-limit` 诊断。绕过补丁 stream 槽的原生写入会到达独立于完成端口的 pipe因此宿主会针对这些字节和不可信伪造通信再次执行账本统计在物化结果前结算过程会持续进行有界 pipe 捕获,直到 worker 完成终止。`maxOutputBytes` 统计外层 `logs` 数组加完成值或失败消息载荷的 JSON 序列化;固定的 `CodeRunResult` 字段名、花括号、有界错误 kind 标签,以及后续呈现空白不计入这份可变载荷账本。未超过上限时会返回精确值;有损完成值属于 `invalid-output`,组合溢出属于 `output-limit`,不会用 inspected string 代替。失败会保留能容纳的已捕获前缀,之后按普通外层 `run_code` 落盘策略处理。
- **空环境**worker 使用 `env: {}``execArgv: []`,既没有环境凭据(比 spawn 命令的清理环境规则更严格),也不会继承 loader 标志。
- **释放资源时等待完全停稳**:清理会进行中的运行标记为 `abort`,并在 resolve 前等待每个 worker 退出。
- **绑定调用被拒绝时使用的异常类属于请求数据**:可选命名空间描述符会指定构造器全局变量,以及用于接收调用失败成员名称的自有属性。worker 会创建并注入该真实类,使 `instanceof` 生效,同时无需硬编码 `tools``ToolCallError`;全局变量无效或冲突的声明会在启动 worker 前失败。失败路径使用模块捕获的错误 intrinsic 与属性定义 intrinsic以及 null-prototype 描述符,因此模型之后的修改无法把被拒绝的绑定变成 worker 崩溃。
- **两个独立预算,因为对端不可信**`computeMs` 统计 worker 实际测得的忙碌时间(轮询 `worker.performance.eventLoopUtilization()`);热循环无法借助待完成的诱饵 dispatch 隐藏,程序等待慢工具时则不累计。`maxWallMs` 为忙碌时间无法观测的情况兜底(例如等待永远不会 resolve 的 promise。二者最终都会调用 `worker.terminate()`,连同步热循环也能终止;堆溢出会表现为 worker 的 OOM 退出(`kind: 'worker-exit'`)。`maxWallMs` 在加载时会对照 `MAX_TIMER_DELAY_MS` 做范围校验:`setTimeout` 会把更长的延迟限制为 1 ms仅有正数校验会放行一个在第一个 tick 就到期的上限。`computeMs` 不需要这道上界,因为它对照的是实测占用率,而不是喂给定时器。
- **中间绑定值是完整 JSON**:绑定参数与 resolve 值会接受迭代式无损 JSON 验证。程序执行前worker 会捕获自己 realm 中的普通容器原型身份,以及只用于外部 realm 的原生函数源码检查,因此构造器槽修改和用户编写的仿冒对象都无法改变容器分类。它还会捕获该 JSON 边界使用的每一个结构与计量 intrinsic以无原型对象创建属性描述符并绕过可变集合原型管理私有遍历状态因此模型对全局对象、原型方法或 `Object.prototype` 上形似描述符字段的修改都无法改变验证、wire 传输或字节计量。值会展平为自身嵌套深度有界的前序 wire 值,供 structured clone 使用并在另一侧迭代式重建。它们没有字节、JavaScript 调用栈或嵌套 structured-clone 深度上限绝不会进入外层输出账本或模型上下文上限仍来自提供方执行器获取限制与进程worker 内存。
- **日志主动流入一个外层账本**consolestdoutstderr 文本按产生顺序经端口传输因此超时或被终止的程序仍会显示已经打印的内容。worker 会精确统计 JSON 字符串的字节数,并在发送完成值和异常诊断前,根据组合预算的剩余量预检;因此,抛出的百万字节 stack 会在 worker 边界变成固定的 `output-limit` 诊断。绕过补丁 stream 槽的原生写入会到达独立于完成端口的 pipe因此宿主会针对这些字节和不可信伪造通信再次执行账本统计在物化结果前结算过程会持续进行有界 pipe 捕获,直到 worker 完成终止。`maxOutputBytes` 统计外层 `logs` 数组加完成值或失败消息载荷的 JSON 序列化;固定的 `CodeRunResult` 字段名、花括号、有界错误 kind 标签,以及后续呈现空白不计入这份可变载荷账本。未超过上限时会返回精确值;有损完成值属于 `invalid-output`,组合溢出属于 `output-limit`,不会用 inspected string 代替。失败会保留能容纳的已捕获前缀,之后按普通外层 `run_code` 落盘策略处理。
- **空环境**worker 使用 `env: {}``execArgv: []`,既不会获得环境变量中的凭据(比 spawn 命令的清理环境规则更严格),也不会继承 loader 标志。
- **dispose资源释放时等待完全停稳**:清理会使进行中的运行 `abort` 失败,并会等待每个 worker 退出后再完成
## 未构建与已构建的 worker 入口
源代码模式通过 Node 原生类型剥离加载只包含可擦除语法的 `src/worker.ts`。其传递运行时闭包只包含 Node 内置模块和相对源模块,因此全新 checkout 绝不需要兄弟工作区包尚未构建的 `lib/` 导出。worker 本地 JSON 快照器会与会话自有的规范边界执行一致性测试;消息端口两侧都会展平并重建已验证值,使应用嵌套永远不会进入 structured clone。构建模式会把兄弟文件 `lib/worker.cjs` 作为文件系统路径传入,因为 pkg 的 VFS Worker hook 要求 CommonJS同一路径也可在普通 Node 下使用。`tests/built-lib.e2e.ts` 固定了 [docs/testing.md](../../../docs/testing.md) 要求的真实加载路径。
源代码模式通过 Node 原生类型剥离加载只包含可擦除语法的 `src/worker.ts`。其传递运行时闭包只包含 Node 内置模块和相对源模块,因此全新 checkout 绝不需要兄弟工作区包package尚未构建的 `lib/` 导出。worker 本地 JSON 快照器会与会话自有的规范边界执行一致性测试;消息端口两侧都会展平并重建已验证值,使应用嵌套永远不会进入 structured clone。构建模式会把兄弟文件 `lib/worker.cjs` 作为文件系统路径传入,因为 pkg 的虚拟文件系统(VFSWorker hook 要求 CommonJS同一路径也可在普通 Node 下使用。`tests/built-lib.e2e.ts` 固定了 [docs/testing.md](../../../docs/testing.md) 要求的真实加载路径。
SDK 接口是默认具名 `WorkerCodeRuntime` `Config`可操作`./worker` 子路径仅作为打包后的 spawn 入口存在wire 协议与启动辅助模块是源代码私有的实现细节。
SDK 对外提供默认具名导出的 `WorkerCodeRuntime`,以及 `Config`运行所用`./worker` 子路径仅作为打包后的 spawn 入口存在wire 协议与启动辅助模块是源代码私有的实现细节。
## 模型体验
@@ -42,13 +42,13 @@ SDK 接口是默认/具名 `WorkerCodeRuntime` 类与 `Config`。可操作的
#### KV Cache 影响
不会直接失效;由具名消费方负责请求前缀变更。
不会直接失效;由上述消费方负责请求前缀变更。
## 已知限制与暂缓工作
- **程序 spawn 的 OS 进程在终止后仍会存活**`worker.terminate()` 只结束线程,比 bash-local 的进程组终止更弱;在容器后端出现前,孤儿清理属于部署职责。
- **程序派生的 OS 进程在程序终止后仍会存活**`worker.terminate()` 只结束线程,比 bash-local 的进程组终止更弱;在容器后端出现前,孤儿进程清理属于部署职责。
- **类型剥离依赖 Node 的实验性 `stripTypeScriptTypes` API**依赖的行为由单元测试固定如其发生变化amarosucrase 是已经点名的直接替代品。
- **`computeMs` 到期最多可能超过一个轮询间隔**:系统每 25 ms 采样一次忙碌时间(内部常量,有意不做成配置)。
- **程序获得一个含 5 方法的 `console` shim**`log``info``warn``error``debug`):有意不提供 Node 的完整 console 接口。
- **程序获得一个含 5 方法的 `console` shim**`log``info``warn``error``debug`):有意不提供 Node 的完整 console 接口。
- **中间绑定值没有字节上限**:程序可以用永远不会成为外层输出的值耗尽进程或 worker 内存。
- **默认 64 MiB 是拒绝边界,不是可恢复存储**:外层落盘只能保存发生 `output-limit` 后返回的有界日志和诊断;在运行时上限之外被拒绝的字节永远不会到达落盘层。

View File

@@ -4,21 +4,21 @@
这是**代码执行 seam**:抽象的 `CodeRuntime` 服务(`ctx.codeRuntime`)只定义代码运行时做什么,即针对宿主提供的一组异步绑定运行一段模型编写的程序,并报告 `{ value, logs, error? }`,而不规定如何实现。
此包是该能力的接口(以 bash 三包结构为模板,参见[能力 seam](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md)):实现通过继承 `CodeRuntime` 并注册服务接入;消费方是工具注册表的 Code Mode它生成面向模型的 SDK并桥接工具分发。两者都由 [Code Mode Agent Note](../../../.agents/notes/implemented/feature/2026-06-15-code-mode.md) 规定,首个实现是 Node worker 线程后端。运行时不了解工具或会话:调用方只向它提供具名异步函数与程序字符串;所有工具形状的内容都留在消费方。
此包package承担该能力三个组成部分中的接口职责(以 bash 三包结构为模板,参见[能力 seam](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md)):实现通过继承 `CodeRuntime` 并注册服务接入;消费方是工具注册表的 Code Mode它生成面向模型的 SDK并桥接工具分发。这两项职责均由 [Code Mode Agent Noteagent 决策记录)](../../../.agents/notes/implemented/feature/2026-06-15-code-mode.md) 规定,首个实现是 Node worker 线程后端。运行时不了解工具或会话:调用方只向它提供具名异步函数与程序字符串;所有工具有关的内容都留在消费方。
## 服务 API`ctx.codeRuntime`
| 成员 | 语义 |
|---|---|
| `run(request)` | 针对请求的绑定执行一段程序。**每一种程序结果都通过 error 字段完成 resolve**:包括解析/转换失败、抛出异常、无效完成值、输出溢出、预算到期、中止或执行基底死亡(由 `CodeRunFailure` 的正交 `kind` 分类表示);只有调用方误用 seam 本身时才 reject例如资源释放后仍提交运行。程序作为异步函数的函数体运行因此顶层 `await``return` 可用,无损 JSON 完成值会成为 `result.value`。 |
| `language` | 只读描述符:`run` 期望的源语言(已知值为 `'typescript'`)。仅供参考,不作门禁;生成语言专用呈现的消费方会对该值执行分支,遇到无法呈现的语言时明确失败。 |
| `run(request)` | 针对请求的绑定执行一段程序。**所有程序失败结果都通过 resolve 结果中的 error 字段报告**:包括解析/转换失败、抛出异常、无效完成值、输出溢出、预算到期、中止或执行基底终止(由 `CodeRunFailure` 的正交 `kind` 分类表示);只有调用方误用 seam 本身时才 reject例如 dispose资源释放后仍提交运行)。程序作为异步函数的函数体运行,因此顶层 `await``return` 可用,无损 JSON 完成值会成为 `result.value`。 |
| `language` | 只读描述符:`run` 期望的源语言(已知值为 `'typescript'`)。仅供参考,不作门禁;生成语言专用呈现的消费方会根据该值选择分支,遇到无法呈现的语言时明确失败。 |
| `isolation` | 只读描述符:执行基底(`'worker-thread'``'process'``'container'`)。供部署与诊断使用,**不构成安全声明**。 |
每个实现都必须遵守以下语义(完整契约见类 JSDoc绑定调用会桥接完整的无损 JSON 参数与 resolve 值seam 层不设字节上限;程序被视为不可信对等方(任意绑定名称都自有属性,格式错误的通信绝不能使宿主崩溃);不同运行之间不保留任何状态;资源释放会终止进行中的运行,并且在完成前等待其退出。
每个实现都必须遵守以下语义(完整契约见类 JSDoc绑定调用会桥接完整的无损 JSON 参数与 resolve 值seam 层不设字节上限;程序被视为敌对对等方(任意绑定名称都会成为自有属性,格式错误的通信绝不能使宿主崩溃);不同运行之间不保留任何状态;dispose 会终止进行中的运行,并且在完成前等待其退出。
## 词汇
`CodeRunRequest``program``bindings``signal?`)携带运行时操作所需的全部内容;默认值解析(时间预算与外层输出上限)属于实现的已验证配置,绝不能是隐藏的 `??`,更不能藏在 `run()` 内部。`bindings``CodeBindingNamespace` 列表(`global` + `functions` + 可选 `errorClass`);每个命名空间会作为一个由异步可调用函数组成的全局对象公开给程序,这些函数返回 `CodeJsonValue`。后者是 seam 本地、与规范 `JsonValue` 结构等价的类型,使接口包保持独立于会话。`errorClass` 描述符点名真实的程序全局构造器,以及用于接收 reject 成员名称的自有属性;运行时不依赖 `ToolCallError` 等消费方术语。`CodeRunResult` 报告无损 JSON 完成值 `value?`、有序的 `logs: string[]``error?``CodeRunFailure``kind` + 可反馈给模型的 `message`)。完整契约见 `src/types.ts`
`CodeRunRequest``program``bindings``signal?`)携带运行时操作所需的全部内容;默认值解析(时间预算与外层输出上限)属于实现的已验证配置,绝不能是隐藏的 `??`,更不能藏在 `run()` 内部。`bindings``CodeBindingNamespace` 列表(`global` + `functions` + 可选 `errorClass`);每个命名空间会作为一个由异步可调用函数组成的全局对象公开给程序,这些函数返回 `CodeJsonValue`。后者是 seam 本地、与规范 `JsonValue` 结构等价的类型,使接口包保持独立于会话。`errorClass` 描述符点名真实的程序全局构造器,以及用于接收被拒绝成员名称的自有属性;运行时不依赖 `ToolCallError` 等消费方术语。`CodeRunResult` 报告无损 JSON 完成值 `value?`、有序的 `logs: string[]``error?``CodeRunFailure``kind` + 可反馈给模型的 `message`)。完整契约见 `src/types.ts`
## 模型体验
@@ -26,11 +26,11 @@
#### KV Cache 影响
不会直接失效;由具名消费方负责请求前缀变更。
不会直接失效;由上述消费方负责请求前缀变更。
## 已知限制与暂缓工作
- **`run()` 是一次性的**`logs` 只有在 `CodeRunResult` resolve 后才能获得seam 不提供活跃程序输出的流式日志或进度接口。
- **`run()` 是一次性的**`logs` 只有在 `CodeRunResult` resolve 后才能获得seam 不提供正在运行的程序所产生输出的流式日志或进度接口。
- **持久 REPL 风格内核已记录为未来工作**:在持久内核后端带来自己的日志方案前,运行之间不保留状态的契约继续有效(参见 [Code Mode Agent Note](../../../.agents/notes/implemented/feature/2026-06-15-code-mode.md))。
- **目前只提供 worker 线程后端**`'process'``'container'` 是已经声明但没有实现的已知 `isolation` 值;安全边界需要等待容器后端。
- **目前只提供 worker 线程后端**`'process'``'container'` 是已经声明但没有实现的已知 `isolation` 值;安全边界需要等待容器后端。
- **中间绑定值没有字节上限**:实现仍受 structured-clone 成本与进程内存约束,而提供方或执行器可能已经应用自己的获取上限。