前言¶
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 倉庫。