xmoon/dsh-profile-settings:DeepSeek Harness 多配置文件设置覆盖

前言

DSH 的标准设置机制通过 ctx.settings 管理配置。为特定配置文件(如 web)定制这些设置通常需要在全局 settings.yaml 中手动管理复杂的覆盖逻辑。xmoon/dsh-profile-settings 插件在官方用户设置机制之上添加了一个透明的配置文件覆盖层,使每个配置文件拥有自己的覆盖文件(settings.patch.yml),而不会破坏现有的设置行为。

介绍

这是一个 DSH 配置文件插件,由 XMoon 维护。它添加了配置文件特定的设置覆盖,将全局 settings.yaml 与 profiles/<name>/settings.patch.yml 分开,允许每个配置文件在继承全局设置的同时覆盖特定命名空间。

核心功能

  • 在 ctx.settings 下添加配置文件特定的设置覆盖。
  • 透明层叠:全局 settings.yaml + profiles/<name>/settings.patch.yml。
  • 递归对象合并,数组与标量整体替换。
  • 支持 YAML !unset 指令以显式隐藏继承的值。
  • 提供 Web UI,展示每个字段的来源标记(Default / Composition / Global / Profile / Masked)及操作按钮。
  • 支持热重载,配合写入锁和事务保证文件完整性。

安装与启用

此插件需要配置文件捆绑包包含 @deepseek-ai/dsh-base(所有内置的 web / headless 模板均具备此条件)。安装命令如下:

dsh plugin --profile web add @xmoon76/dsh-profile-settings

安装过程会自动将包添加到 dsh.profile.bundles。重启 Harness 后,插件会执行以下操作:
1. 禁用基础 settings 行(@deepseek-ai/dsh-settings-file)。
2. 插入拥有 ctx.settings 的新行。

注意:一个组合只能拥有一个 ctx.settings 拥有者。如果基础行仍处于活动状态且未完全被禁用,引导过程会因 Cordis 重复服务错误而失败。

配置

插入的行默认配置如下(通常无需修改):

key default meaning
profile auto-detected 显式指定的活动配置文件名称
globalPath $DSH_HOME/settings.yaml 全局设置文档路径
profileFile settings.patch.yml 配置文件目录内的覆盖文件名
dshHome $DSH_HOME 或 ~/.dsh Harness 主目录
watch true 热重载两个文档
debounceMs 100 监听器写入稳定窗口
writable true 允许进程内写入覆盖文件

活动配置文件的解析顺序为:显式 profile 配置 -> 安装位置(profiles/<name>/node_modules/…)-> 启动器参数 --profile <name> -> DSH_PROFILE 环境变量。若无法确定,引导失败。

Overlay 文件示例

Overlay 文件位于 $DSH_HOME/profiles/<name>/settings.patch.yml。文件由人工编辑或通过 settings 命令修改,进程内的写入操作会落在此文件中,而非 settings.yaml。

# $DSH_HOME/profiles/web/settings.patch.yml
agent-default-model:
  provider: pi-ai
  model: gpt-5.6

permission:
  mode: danger-full-access

some-plugin:
  endpoint: !unset

纯 YAML 值用于覆盖;!unset 会隐藏较低层的值(继承值被删除,除非覆盖层提供了新值)。这些掩码不会进入最终解析的 JSON 文档,UI 中不会将其作为值显示。

Settings 命令

插件挂载后,ctx.profileSettings 和 settings 命令族可用:

settings layers [ns [path]]        查看每个叶子节点的来源证明
settings get <ns.path>              获取有效值
settings set <ns.path> <value>      写入配置文件覆盖
settings unset <ns.path>            删除覆盖值(重新继承)
settings mask <ns.path>             写入 !unset
settings unmask <ns.path>           移除掩码
settings reset <ns>                 对覆盖层执行 replace({})
settings promote <ns.path>          将值上移至全局文档
settings demote <ns.path>           将值下移至配置文件覆盖
settings migrate <ns.path> [--copy] 移动全局值到覆盖层(带 .bak 时间戳备份,--copy 保留原值)
settings diff [ns]                  叶子级全局与覆盖的差异
settings ui [ns]                    机器可读的层快照(Web UI)
settings profile                    查看活动配置文件和文档路径

Web UI

插件包含一个浏览器端 (dsh.client)。Web 设置面板增加了一个“配置文件设置”部分,显示每个字段的来源标记、有效值以及操作(设置/取消设置/掩码/提升/重置等)。所有主机交互通过注册在主机端的 /profile-settings 回环 RPC 通道进行,不涉及会话上下文或命令日志。

并发模型与限制

  • 进程内操作:普通的 update/replace/mutate 遵循官方设置语义(命名空间序列化队列、expectedRevision 冲突检测)。
  • 跨进程文件完整性:使用写锁 + 原子重命名保证。
  • 跨进程自定义层操作(promote/demote/migrate/mask/unmask):使用固定顺序的锁和 fence,确保事务一致性,每次文本更改都会推进层修订。

限制与失败模式:
* 需要 Node >= 22.6。
* 引导时配置文件不可解析、覆盖根不是 map、非对象命名空间、数组中存在 !unset、不支持的 YAML 标签、覆盖路径逃逸配置文件目录、全局与覆盖指向同一文件、重复 ctx.settings 拥有者,均会导致引导失败。
* 热重载期间临时无效的 YAML 会触发警告,但保留最后一个有效版本。

总结

此插件为 DSH 配置文件提供了标准化的设置管理方案,无需修改底层设置逻辑即可实现多配置文件隔离。更多细节请参考 目录页 或 GitHub 仓库。

羽毛球分组比赛记分
小程序二维码

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

小夜