dsh-settings-ui:DeepSeek Harness 插件的统一设置页 UI 套件

前言

DSH 的理念是「一切皆插件」,插件多了,设置界面也会跟着多起来。给插件写设置界面是一件重复劳动:组件要自己写,样式要自己调,还要处理 load / save / busy / error / saved 提示、revision 冲突这一整套状态逻辑。每个插件各写各的,风格和官方设置页对不上,用户在不同插件之间来回切换时体验也是割裂的。

dsh-settings-ui 解决的就是这个问题:它把设置页 UI 和状态逻辑抽成一个可复用的服务,插件通过 ctx.settingsUi 拿到现成的组件、声明式表单和设置状态机,不必再手写 UI。下面介绍它的定位、功能和用法。

这是什么

dsh-settings-ui 是一个面向 DeepSeek Harness 插件的统一设置页 UI 套件加浮层面板套件,由 KaramachiA217 维护,MIT 许可证,仓库附 LICENSE 文件。从 package.json 的 dsh.client.platform 字段看,它面向 web 平台。

它对外暴露 ctx.settingsUi 服务,其他插件用这个服务构建设置区块和浮层面板,风格与 dsh-better-sidebar 及 --dsw-* 语义令牌对齐——不需要自己写组件、CSS,也不需要自己处理 load / save / busy / error / saved / revision 冲突的状态逻辑。

核心功能

三级 API

  • ui.pluginCard():rc7 官方 Plugins 标签页的插件配置卡片,经官方 ctx.settingsScope 持久化;
  • ui.section():经典设置页卡片;
  • ui.overlay() / ui.Panel / createPanelStore:自由浮层,支持拖拽、最小化、z-order、位置持久化,经 storage 事件跨标签页同步。

原子组件族

套件提供一组原子组件:SectionHeader / Field / TextInput / TextArea / Select / Button / Switch / Checkbox / Radio / Card / StatusDot / Badge / Spinner / Tabs / Banner / EmptyState / List / Dialog / ErrorBoundary / toast

声明式表单

Rows 渲染字段描述;createSettingsStore + useSettings 处理 load / save / busy / error / saved-flash / revision 冲突,后端可跑在 fenced route 或官方 settingsScope 上。

向后兼容与自愈

向后兼容:这个插件只新增服务,直接 ctx.slots.inject('settings.section', ...) 的旧用法不变。

自愈能力:section() / overlay() / pluginCard() 自动包裹错误边界,单个卡片渲染崩溃只折叠该卡片,不影响整个设置页。

与官方契约对齐

套件只通过官方槽位/服务注册(settings.plugin.item / settings.section / shell.overlay / settingsScope / locale),.sui-* 样式从 --dsw-* 令牌解析,不导入官方卡片 chrome(value-import purity gate),自己渲染令牌对齐的外壳并自持表单、状态与可访问性。pluginCard 的 chrome 默认采用官方卡片模型:collapsed layer-3 → expanded layer-2、disclosure header、字段分隔线、discard/save footer。

安装与启用

先做安装。用官方 CLI 一步完成:添加依赖,reconcile 后追加到 dsh.profile.bundles

dsh plugin --profile <profile-name> add dsh-settings-ui

后续升级用同一命令加 @latest 后缀即可。

再把它加入 profile bundles。host 已提供 peers 时,消费者不需要把它声明为 peer dependency。下面是 README 给出的示例,dependencies 里的版本号按实际情况填写:

{
  "dependencies": { "dsh-settings-ui": "^0.2.22" },
  "dsh": { "profile": { "bundles": ["dsh-base", "dsh-web-app", "dsh-settings-ui", "..."] } }
}

一个安装时的小坑:pnpm v11 的 minimumReleaseAge 供应链冷却机制,会让全新发布后 24 小时内的安装静默回退到上一版本。可以在 profile 的 pnpm-workspace.yaml 里加 minimumReleaseAge: 0,或者等一天再装。

本地开发时,先用 npm pack 构建 tarball,再用同一命令从本地安装,也可以用 file: 依赖:

npm pack
dsh plugin --profile <profile-name> add ./dsh-settings-ui-<ver>.tgz

注意 rc.6 下的已知差异:link: 开发挂载会 ESM 解析失败,需改用 file: tarball。

典型用法:pluginCard()

rc7 下,官方给插件设置的推荐路径是 Plugins 标签页的配置卡片(按 settings 命名空间 keyed 的 settings.plugin.item 槽位),经官方 ctx.settingsScope 持久化。pluginCard() 在这个契约之上提供带套件外壳的卡片,不用手写 scope 绑定和状态逻辑:

const card = ctx.settingsUi.pluginCard({
  key: 'my-plugin',                 // 必填,等于 settings 命名空间,也是标签页 key
  header: { title: '我的插件', desc: '一句话说明' },
  fields: [
    { key: 'enabled', type: 'switch', label: '启用' },
    { key: 'endpoint', type: 'text', label: '服务地址' },
  ],
})
// card.store.setField('enabled', true)

调用之后不需要再做别的:store 内部调用 ctx.settingsScope.bind({ namespace: key }),每次修改经官方 revision fence 即改即存。

几个可选项:

  • content: (ctx) => ...:完全自定义主体;
  • showIn: 'both' / 'settings-page':让卡片同时在经典设置页露出;
  • chrome: 'minimal':去掉套件的卡片外壳。

关于家族单轨:新的设置卡片建议优先用 pluginCard()(官方 Plugins 标签页),避免一半在设置页、一半在 Plugins 标签页的家族分裂。section() 对既有消费者和 rc6 / headless 环境继续完全支持,已经在用的不需要迁移。

兼容性与环境要求

  • 已在 dsh 0.1.0-rc.5(官方桌面 shell、完整 profile 测试)验证;
  • rc.6 已验证(2026-08-17):rc.5 与 rc.6 共享同一上游提交 47f9438,仅 npm 版本号变化,零适配;
  • rc.7(0.3.0,2026-08-20)已适配:pluginCard() 面向 keyed settings.plugin.item 槽位 + 官方 ctx.settingsScope;经典面(settings.section / settings.general.item / shell.overlay)在 rc.7 不变,section() / overlay() 继续可用。

依赖方面:peerDependencies 为 @deepseek-ai/cordis >=4.0.0-rc.0@deepseek-ai/dsh-client-runtime >=0.1.0-rc.0@deepseek-ai/dsh-client-ui-slots >=0.1.0-rc.0react ^18.2.0;engines 要求 node >=20;dsh.client.platform 为 web,会 inject 三个 @deepseek-ai 客户端运行时/UI 包。

已知限制:同一页面挂载多个 ToastHost 会显示相同的 toast,每页只应挂载一个 host。范围外(官方契约限制):并行侧边栏席位(sidebar.workspaces / sidebar.settings 为单例)和浅色主题。

开发与质量门禁

如果要参与开发或本地验证,仓库提供三步命令:

pnpm install
npm run ci
npm test

npm run ci 是 5 步门禁:语法 + 单元测试 + 密钥扫描 + 净化 + pack 白名单;npm test 基于 node:test,共 45 个单元测试。

Roadmap 方面:1.0.0 计划提供 ui.describeForm,消费官方 settings.describe 的 schemastery schema 自动渲染表单,支持 redactSecrets 只写输入与 revision 冲突处理;工程上计划对 .d.ts 与实现的漂移做自动检查;维护承诺是上游 rc 漂移时重跑 contract-diff 方法论,反馈走 GitHub discussions。

适用场景与注意事项

适合谁:要给自己的 DSH 插件加设置界面、但不想手写组件和状态逻辑的插件作者;希望多个插件的设置风格保持一致、并跟随官方设置页演进的场景。

安装前必须清楚一点:插件以当前 dsh 进程的权限运行,装一个插件等于把它的代码跑进你自己的环境。dsh-settings-ui 是 MIT 许可证,源码公开在 GitHub,安装前应自行检查源码与许可证,确认可信再装。

小结

dsh-settings-ui 把 DSH 插件设置界面里重复的部分——组件、样式、状态机——收进一个 ctx.settingsUi 服务:三级 API 覆盖从官方 Plugins 卡片到经典设置页再到自由浮层的需求,与官方契约对齐、向后兼容,单个卡片崩溃也不会拖垮整个设置页。如果你在写带设置的 DSH 插件,可以直接从 pluginCard() 试起。

  • 社区插件目录页:https://www.skillhub.cn/plugins/KaramachiA217/dsh-settings-ui (独立社区站点,与 DeepSeek / 幻方无官方从属关系)
  • GitHub 仓库:https://github.com/KaramachiA217/dsh-settings-ui
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye