加载顺序(生效配置的分层)
生效配置在空根之上按固定顺序逐层组合,后应用的层按行胜出。
| 顺序 | 层 | 说明 |
|---|---|---|
| 1 | profile 的 dsh.profile.bundles 列表 | 各组合包 patch 按列表顺序,先是 dsh-base,再是每个已安装组合包按其加入顺序 |
| 2 | profile 自己的 cordis.patch.yml | 用户 profile 级的 patch 层 |
| 3 | home 级的 $DSH_HOME/cordis.patch.yml | 各 profile 共享的机器本地偏好 |
| 4 | 每个 --patch <path> overlay | 按 argv 顺序 |
- 应用参数不是另一层 patch;表层组合包通过普通应用自有服务解析它们。
- 后应用的层按行胜出,且 patch 会替换目标行的整个 config 值,而不是深度合并各键。
动手:安装 hello-plugin 进 profile
dsh plugin --profile <name> <args...> 在 profile 目录内转发给 pnpm,所有 pnpm 子命令都可用。
1dsh plugin --profile demo add ./hello-plugin
- 首次使用会初始化 profile,
@deepseek-ai/dsh-base成为第一个组合包。pnpm 链接该 checkout;dsh 因该包声明了dsh.bundle,把它追加进dsh.profile.bundles。
生成的 profile 的 package.json:
1{
2 "name": "dsh-profile-demo",
3 "private": true,
4 "dependencies": {
5 "dsh-hello-plugin": "link:/path/to/hello-plugin"
6 },
7 "dsh": {
8 "profile": {
9 "bundles": [
10 "@deepseek-ai/dsh-base",
11 "dsh-hello-plugin"
12 ]
13 }
14 }
15}
验证与启动:
1dsh --profile demo --dump-config # 会显示一个 "# == dsh-hello-plugin" 层
2dsh --profile demo
移除:
1dsh plugin --profile demo remove dsh-hello-plugin # 同时移除依赖和对应的层
patch 按 id 整行替换(不是深度合并)
| 合并方式 | 行为 | dsh 的选择 |
|---|---|---|
| 深度合并 | 只覆盖改动的键,其它键自动保留 | 不是这样 |
| 整行替换 | 按 id 整行替换 config 值,必须重述所有键 | dsh 采用 |
- 推论一:patch 可以按 id 覆盖前面各层的行(如 dsh-web-app 覆盖 dsh-base 的行),但必须重述该行需要的每一个键,而不是只写改动的那个。
- 推论二:用户可以在自己 profile 的
cordis.patch.yml中覆盖你的行,无需改动你的包。所以优先给出用户大概率会保留的配置默认值,其余交给 schema 承担。 - 内置组合包名称始终从 dsh 安装目录本身解析;pnpm 只管理树外的包,所以组合包可以放心依赖
@deepseek-ai/dsh-base存在且与安装保持一致。
自测
- 四层顺序是什么?→ bundles → profile patch → home patch →
--patchoverlay - 为什么 patch 要重述所有键?→ 因为 patch 是整行替换而非深度合并
- 如何核对每层来自哪个组合包?→
dsh --profile demo --dump-config打印叠加后的生效配置