第 1 章:启动入口与配置档案(Profile)
1. 本章定位
先把 dsh 看成“插件树启动器”,而不是一个写死行为的 CLI。新版同时提供 web、headless、sdk、sdk-minimal、acp 五类配置档案(Profile)。
2. 学习目标
- 解释 Profile、组合包(Bundle)与补丁(Patch)的叠加关系。
- 从
apps/cli/src/bin.ts追到runProfile()。 - 区分启动时重载与运行时插件重载。
- 用配置 dump 定位“参数由哪一层消费”。
3. 前置知识
把 Profile 类比为前端应用入口,Bundle 类似可复用 preset,Patch 类似环境覆盖。局限是 Patch 操作插件树条目,顺序和条目 ID 都是行为,不是普通对象深合并。
4. 对应源码
apps/cli/src/bin.ts:28:动态调用runProfile()。apps/cli/src/profile-boot.ts:209:Profile 启动入口。packages/boot/app-boot/src/profile.ts:139:五个内置 Profile。packages/boot/app-boot/src/profile.ts:166:DEFAULT_PROFILE_BUNDLES。
5. 工作原理
启动器解析 invocation,选择 Profile,按声明顺序读取 Bundle,再叠加 Profile、Harness Home 和 --patch 覆盖,最后交给 Loader 激活 Cordis 插件。启动时变化需要重新准备配置;只有进入 Loader 管理且声明可重载的插件行为才属于运行时重载。
6. 执行流程
无图回退:dsh → 解析 invocation → runProfile() → 准备 Profile → 顺序叠加 Bundle/Patch → Loader 挂载插件 → 启动 Web、Headless、SDK 或 ACP 表面。
7. 关键源码讲解
apps/cli/src/bin.ts:28 不创建 Agent,只把控制权交给 Profile 启动。packages/boot/app-boot/src/profile.ts:139-155 明确列出五类表面,packages/boot/app-boot/src/profile.ts:166 决定默认 Bundle。新增表面优先组合 Bundle;只有公共启动语义变化才修改 boot 核心。
8. 调试与观察方法
- 断点:
runProfile()与 Profile 准备完成处。 - 观察:Profile 名、Bundle 顺序、Patch 来源、最终条目列表。
- 【已执行并验证】
pnpm dsh --help(见第 9 节验证记录)。 - 【已执行并验证】使用隔离的临时
DSH_HOME执行--profile web --dump-default-config,成功输出 base 与 web Bundle 组合树。 - dump 已失败时,模型尚未调用,不要先排查 API Key。
9. 本章实践任务
用临时目录创建一个只改变非敏感配置的 overlay,比较默认与最终 dump;再移除 overlay,确认恢复。验收:能指出每个字段来自哪个层级,且未修改用户现有 Profile。
10. 常见误区
- 把 Profile 当单文件,而忽略 Bundle 顺序。
- 把启动参数与应用参数混为一谈。
- 认为所有 Patch 都能在线热更新。
11. 自测题
- 五个内置 Profile 分别面向什么表面?
- Bundle 顺序为什么会改变行为?
--patch适合哪类实验?- 配置 dump 失败说明调用链停在哪里?
- 何时应该新增 Bundle,而不是修改 boot 核心?