# dsh-client-ui-settings-plugins

[English](README.md) | 中文

**插件**设置分区及其**插件配置**标签页。该分区拥有标题与紧凑的标签栏；功能插件通过 `settings.plugins.tab` 贡献页面。本包自己的标签页为每个配置由用户拥有的 Host 插件展示一张可展开卡片。卡片展示插件名称及其管辖范围；就地展开后是绑定到该插件 settings 命名空间的手写控件，每个字段标注用户是否覆盖过它，并提供重置回部署组装值的入口。

## 这里会出现什么

“插件配置”标签页读取 Host 服务了哪些 settings 命名空间，并为每个命名空间派发一个 slot 键，因此渲染出来的是两份账本的交集：存活 Host 插件注册的命名空间，以及注册在这些键上的卡片。被服务却无人认领的命名空间什么都不渲染——它归别的界面所有，或本部署没有为它提供浏览器半侧；而命名空间未被本部署服务的卡片根本不会被派发，因此未组装的插件不留任何痕迹，也不会挡住那行空态文案。空态文案要等 Host 的第一次答复，因此一次尚未答复的读取绝不会被读成“本部署没有可配置的插件”。卡片按自身注册的顺序出现；对同一个包一起安装的卡片这是稳定的，对跨插件的卡片则不稳定：包与包之间的 apply 顺序是无约束的。

本包自带的卡片覆盖 shell 执行器（`bash`）、agent 循环的工具调用并行度（`agent-loop`）以及 DeepSeek 搜索提供方（`web-search-deepseek`）。

## 扩展点

本分区声明根级列表 slot `settings.plugins.tab`，其标签会成为有序标签页。某个标签页首次被选择后会保持挂载，因此本地草稿与只读快照在切换标签页时不会丢失。本包注册自己的 `configurable` 贡献，由它声明嵌套的 `settings.plugin.item` slot——以卡片所编辑的 settings 命名空间为键。带浏览器半侧的插件把自己的卡片注册在自己的命名空间上，并拥有它的全部：外观、控件与文案。以命名空间为键，正是在本仓库之外分发的插件能出现在这里的原因——它在 Host 上注册命名空间、在浏览器里注册卡片，由标签页把两者配对，而无需知道命名空间意味着什么。标签页遵循贡献的 `order`；卡片遵循注册顺序。

## 写入

卡片暂存用户输入，只有用户保存时才写入。每个控件渲染的都是暂存文本，因此屏幕上所见即保存后所存；**放弃修改**丢弃这些草稿，持有未保存修改的卡片即使收起也会在标题上标明。重置暂存的是组装默认值而非立即写入；字段不接受的草稿会阻塞保存，而不是被丢弃。

保存时，每个暂存字段都通过客户端 settings scope 写入，该 scope 用读取时的命名空间 revision 为每次写入设栅，因此已与文档脱节的表单会被拒绝，而不是覆盖并发变更。某个值是否被接受只有 Host 说了算——schema 表达不了的约束归它的校验器所有——因此卡片在写入后回读分节，报告没有落盘的保存，并保留这些草稿供用户修改。

密钥也可能从别的表层写入——模型页寻址的是同一个引用——而那不改变任何 settings 分节，因此卡片会在转发来的 `credentials/updated` 事件报告它所关注的引用时重读。

字段是否被覆盖，取决于它是否出现在原始用户层中，而非取决于它的值；重置会清除该字段，使其重新继承组装层。secret 角色的字段绝不搭乘响应，因此密钥控件初始为空、只报告是否已配置，并经由 credentials 领域而非 settings 分节写入；空草稿不写入任何东西，保留已存密钥。

## 模型体验

无。该分区渲染浏览器配置 UI；它写入的值只通过拥有这些值的插件到达模型，而这些效应各由其拥有方的包记录。

#### KV Cache 影响

无；该包既不组装也不发送提供方请求。

## 已知限制与暂缓事项

- **只有宿主平面的插件会出现**——由 agent preset 挂载的插件把配置内联在该 preset 的 `agent.cordis.yml` 中，且根本无法注册 settings 命名空间（同一 preset 挂载第二个会话时会因重复注册而失败），因此本分区不会列出它。编辑那些值仍是 preset 编辑器的职责。
- **卡片仍然需要一份浏览器 bundle**——浏览器半侧必须是按客户端模块系统的 lazy-CJS factory 格式构建的 `dsh.client` 包，而产出它的 `clientBundle` 预设位于 `packages/client/tsdown.client.ts`，并非已发布的包，因此本仓库之外的插件得自行复刻该构建。bundle 纯净度门禁同时禁止以值的形式导入本包的卡片外观与表单模型，所以这样的卡片要自行拥有暂存与 revision 设栅。
- **被服务的命名空间只在两种信号上重读**——协议通告的是 settings 文档提交与连接重置，而非注册行为，因此在标签页读取之后才被其拥有方注册的命名空间，要等下一次文档提交或重连才会加入列表。
- **shell 卡片跟随被组装的执行器**——POSIX 与 PowerShell 两个执行器家族共用 `bash` 命名空间，因为一个宿主只组装其中之一，所以被服务的 schema 随平台不同（PowerShell 多出 `pwshPath`），尽管卡片在两者下编辑的都是同样两个字段；而两者都不组装的部署不会显示这张卡片。
