DSH 高级设置(Settings Plus)
English · 中文
██████╗ ███████╗ ██╗ ██╗
██╔══██╗ ██╔════╝ ██║ ██║
██║ ██║ ███████╗ ███████║
██║ ██║ ╚════██║ ██╔══██║
██████╔╝ ███████║ ██║ ██║
╚═════╝ ╚══════╝ ╚═╝ ╚═╝┌─────────────────────────────────────────────────────────────┐
│ dsh-settings-plus │
│ DeepSeek Harness 官方设置的 plus │
│ 表单级 + 文件级配置管理 │
│ + 面向所有插件的开放注册 SDK │
│ │
│ 175 个测试 | MIT | TypeScript ESM | Cordis v4 │
└─────────────────────────────────────────────────────────────┘dsh-settings-plus 是 DeepSeek Harness 官方设置的 plus。官方入口是单个设置表单;本插件提供的是设置管理面:所有已注册的 settings namespace 与所有已挂载插件的组合配置,既可以表单方式浏览编辑,也可以文件方式浏览编辑。任何插件都能通过薄 SDK 注册自己的设置 namespace。
本仓库是自包含的独立 ESM Cordis 插件仓库。DSH 宿主是成品包的运行时消费者,不是源码或构建输入。
<p align="center"> <img src="https://img.shields.io/badge/tests-175%20passed-2ea043" alt="175 个测试通过"> <img src="https://img.shields.io/badge/license-MIT-94a3b8" alt="MIT 许可证"> <img src="https://img.shields.io/badge/language-TypeScript-3178c6" alt="TypeScript"> <img src="https://img.shields.io/badge/module-ESM-38bdf8" alt="ESM"> <img src="https://img.shields.io/badge/framework-Cordis%20v4-f97316" alt="Cordis v4"> <img src="https://img.shields.io/badge/ecosystem-dsh--plugin-8b5cf6" alt="dsh-plugin topic"> <img src="https://img.shields.io/badge/version-0.0.1-64748b" alt="版本 0.0.1"> </p>
已发布至 dsh-plugin topic,PR 进入 awesome-DSH-plugin,dsh-market 跟随。
架构
flowchart LR
subgraph HOST["DSH 宿主(运行时)"]
REG["cordis registry:settings namespace + 组合行"]
GW["gateway:exposed-namespaces 白名单"]
FS["ctx.fs 形态通道"]
end
subgraph PLUS["dsh-settings-plus(本仓库)"]
C1["C1 宿主爬取"]
C2["C2 表单级编辑(浏览器半)"]
C3["C3 文件级编辑"]
C4["C4 插件 SDK"]
CLIENT["lib/client.js"]
end
C4 -->|注册用户 namespace| C1
C1 -->|枚举,secret 脱敏| REG
C1 -->|经 settings seam + 版本守卫写入| REG
C1 -.->|Fabric 加宽,可选| GW
C3 -->|原子读写 + expected-version 守卫| FS
C2 -->|打包为| CLIENT
C2 -->|经 catalog source seam 读取,wire 待落地| C1四大能力
🔭 C1 · 宿主爬取
(src/crawler.ts、src/service.ts、src/fabric.ts)
只读 crawler 枚举所有已注册的 settings namespace(ctx.settings.describe + secret 脱敏)与所有已挂载插件的组合配置(schemastery Config + 行 id,来自 cordis 运行时 registry)。bundle 以 ctx.dshSettingsPlus 宿主服务发布:listNamespaces、listCompositionConfigs、updateComposition、removeComposition。写操作经宿主 settings seam + 乐观并发版本守卫。普通 cordis.yml 组合行不可经服务写入(请用文件编辑面或 cordis.patch.yml)。Fabric 绑定在加载时加宽 gateway 的 exposed-namespaces 白名单:可选挂载,缺失时安全 no-op。
🎛️ C2 · 表单级编辑
(src/client/)
浏览器半注册 settings.section 贡献:始终存在的 高级设置 入口(order 30)、catalog 无数据时的 loading/empty/error 三态状态行、每 catalog 条目一个分区,按签名差分(${key}\u0000${label})reconcile。通用 schema 表单渲染器(src/client/schema-form.tsx)渲染白名单控件:string/number/boolean 原生、const-only union 下拉、嵌套对象分组、其余 JSON textarea 兜底。secret 占位协议保证占位永不回传、留空保持原值、显式输入才提交。逐字段 reset 用 unset 操作,绝不写值。revision 冲突给出重载提示,restart 提示说明宿主何时需要重启。渲染器已完整实现并通过测试;接入数据分区随宿主 wire 面落地(见"已知限制")。
🗂️ C3 · 文件级编辑
(src/file-browser.ts、src/file-store.ts、src/yaml-editor.ts、src/patch-validator.ts、src/hmr-aware.ts)
封闭配置清单(可写的 $DSH_HOME 根 YAML 文件 + 每 profile 的 cordis*.yml,bundle 层只读展示)经 realpath 越界校验。读写经注入的 ctx.fs 形态通道原子进行,带字节上限与 expected-version 写守卫。YAML round-trip 保留注释。语义校验拒绝会破坏文档的补丁编辑。HMR 说明诚实:插件不拥有 watcher,宿主已热重载 cordis.patch.yml 与 settings.yaml,保存策略只保证原子写。
🧩 C4 · 开放注册 SDK
(src/sdk.ts、[docs/sdk-contract.md](docs/sdk-contract.md))
其他插件通过 registerUserSettings(实注册 + 显式移除 disposer)、defineSettingsSection(声明式,无副作用)、settingsNamespace(命名品牌,^[a-z][a-z0-9-]*$)在宿主上注册自己的 settings namespace。注册随调用方 fiber 回收,secret 语义归宿主 seam,重复注册在宿主响亮报错。
官方设置 vs dsh-settings-plus
| 领域 | 官方设置入口 | dsh-settings-plus |
|---|---|---|
| 编辑形态 | 单个设置表单 | 表单级编辑,外加文件级编辑面 |
| 可浏览范围 | 宿主设置表单 | 所有已注册 settings namespace 与所有已挂载插件的组合配置,secret 脱敏 |
| 文件写入 | 不在范围内 | 封闭可写清单,原子写 + 版本守卫 |
| 插件自定义设置 | 仅宿主管理 | 任何插件经 SDK 注册自己的 namespace |
来自真实 DSH profile 的实机截图——左为官方设置入口,右为 SDK 注册 namespace 渲染出的插件设置页:
<p align="center"> <img src="pic/xxx251.png" alt="官方设置入口" width="48%"> <img src="pic/xxx312.png" alt="插件设置页" width="48%"> </p>
设计原则
- 默认只读。 crawler 从不写入;文件浏览器只枚举与校验。
- secret 归宿主 seam。 占位永不回传,脱敏在 schema 遍历中完成。
- 写入有守卫。 每条写路径都有 expected-version 守卫、字节上限与 realpath 越界校验。
- 不自建 watcher。 插件从不擅自重启你,只如实说明宿主已经热重载什么。
- 响亮失败,安全降级。 畸形 Fabric facade 响亮报错;缺失 facade 是安全 no-op。
快速开始
1. 安装 到 DSH profile(对本仓库做 file: 安装):
dsh plugin --profile <name> add file:/<repo-dir>/dsh-settings-plus2. 启动 profile。 包 manifest 声明 dsh.bundle.patch(cordis.patch.yml),在所选 profile 的运行时上组合三行:dsh-settings-plus、dsh-settings-plus-invariant companion、以及一个禁用状态的 cordis-fabric 桩(加载时加宽 gateway 的 exposed-namespaces 白名单,运行时绑定在 src/fabric.ts)。补丁只组合插件;不改宿主源码、编译器设置或构建脚本。profile 的 node_modules 提供裸名 peer 依赖。
3. 打开设置导航。 高级设置 入口出现,带 loading/empty/error 三态状态行。每条目数据分区随宿主 wire 面落地后渲染(见"已知限制")。
插件作者的 SDK 用法
在插件 apply 内注册一个 namespace,随调用方 fiber 回收:
import { Context } from 'cordis'
import z from 'schemastery'
import { registerUserSettings } from '@oneinitai/dsh-settings-plus/sdk'
export const name = 'my-plugin'
export const inject = ['settings']
const MySection = z.object({
host: z.string().default('localhost'),
token: z.string().role('secret'),
})
export function apply(ctx: Context) {
ctx.effect(() => registerUserSettings(ctx, 'my-plugin', MySection, { applies: 'live' }))
}注册后 namespace 立即进入宿主设置面:crawler 的 ctx.dshSettingsPlus.listNamespaces() 会包含它,配置 UI 自动渲染其 schema。完整契约(命名、secret、生命周期、去重语义)见 [docs/sdk-contract.md](docs/sdk-contract.md)。
浏览器半
src/client/ 是 Web bundle,以 lib/client.js 提供(exports map ./client)。它注册 settings.section 贡献与 dsh-settings-plus locale namespace([src/client/locales.ts](src/client/locales.ts) 中 zh/en 双字典;中文是产品文案,英文镜像,en satisfies Record<keyof typeof zh, string> 保证对齐)。catalog 通过可注入的 settingsPlusCatalog source seam 读取。生产默认是诚实的本地空源(宿主 wire 面落地前),因此设置导航显示状态行的 empty 阶段,尚无数据分区。
已知限制
如实陈述:
- defer 到 v2(计划约定):聚合配置页、per-namespace 拒绝名单、导出/导入、required secret 保存修复。
- 宿主 wire 面处于诚实降级状态:T16 分发冒烟验证了插件安装/加载与服务挂载;宿主 wire 面(浏览器 catalog 数据通道、真实
ctx.fs适配器、Fabric patch 端到端)待宿主升级后补验证。当前为诚实降级状态:catalog 空源、Fabric no-op、文件写走本地FsLike通道。 - Fabric 依赖姿态:
cordis-fabric在绑定时从宿主上下文可选加载。未挂载 facade → 安全 no-op(桩行保持禁用,gateway 保持默认白名单);facade 挂载但畸形 → 响亮报错。 updateComposition的写范围:只有已注册 settings namespace 的 id 可经服务写入;普通cordis.yml组合行响亮失败,须经文件编辑面或cordis.patch.yml修改。
后续计划(Roadmap)
- L2 浏览器 RPC 接入:把客户端 catalog 从空本地源接到真实宿主数据通道。
- L3 外部 HTTP API:按需将 settings 服务暴露为外部 HTTP 接口。
- 宿主版本兼容范围锁定:维持宿主版本范围锁定(见
peerDependencies),宿主升级后补验证 wire 面。
独立开发
所有命令都在本目录运行:
pnpm install
pnpm run verify:self-contained
pnpm run typecheck
pnpm test
pnpm run build
pnpm run prepareverify:self-contained 拒绝文件系统依赖 spec、离开仓库的编译器路径、外部或损坏的 Markdown 链接、绝对工作站路径和格式错误的 bundle skill 元数据。typecheck 同时检查声明工程与源码平面测试。build 是开发/CI 类型安全门禁;prepare 产出消费者侧产物(含 lib/),供 Git 与 tarball 安装。
仓库布局
.
├── .agents/skills/ # 仓库本地插件开发工作流
├── docs/
│ ├── dsh-plugin-contracts.md # 所有插件 skill 共享的本地契约
│ └── sdk-contract.md # 注册 SDK 契约(C4)
├── patches/ # 依赖补丁与 DSH host patch 契约
├── scripts/ # prepare、verify-self-contained、补丁辅助
├── src/
│ ├── index.ts # Loader 面向的函数插件命名空间
│ ├── config.ts # 可序列化 schema 与解析后的默认值
│ ├── runtime.ts # Cordis 激活与宿主边界接线
│ ├── invariant.ts # 包自有的 invariant companion
│ ├── crawler.ts # 只读设置/组合枚举(C1)
│ ├── service.ts # ctx.dshSettingsPlus 服务面(C1)
│ ├── fabric.ts # 可选 gateway 白名单加宽(C1)
│ ├── sdk.ts # 开放注册 SDK(C4)
│ ├── file-browser.ts # 封闭配置清单 + 越界校验(C3)
│ ├── file-store.ts # 原子读写 + 版本守卫(C3)
│ ├── yaml-editor.ts # 保留注释的 YAML round-trip(C3)
│ ├── patch-validator.ts # 语义补丁校验 + 自保护(C3)
│ ├── hmr-aware.ts # 保存的 HMR 说明(C3)
│ └── client/ # 浏览器半,以 lib/client.js 提供(C2)
│ ├── index.ts # settings.section 注册 + 状态行
│ ├── catalog.ts # 可观察 catalog store + 可注入 source seam
│ ├── component.tsx # 入口 / 状态行 / 数据分区组件
│ ├── schema-form.tsx # 通用 schema 表单渲染器
│ ├── form-logic.ts # 表单逻辑 + secret/reset/冲突协议
│ └── locales.ts # zh/en locale 字典
├── tests/ # 宿主 spec(node)与客户端 spec(jsdom)
├── AGENTS.md # 仓库本地贡献契约
├── LICENSE # MIT
├── README.md / README.zh.md # 仓库与使用契约
├── cordis.patch.yml # profile bundle 贡献
└── package.json # 导出、peers、dsh.bundle.patch许可证
[MIT](LICENSE),Copyright (c) 2026 oneinitAI。贡献规则见 [AGENTS.md](AGENTS.md)。