# 04 · 部署指南 > 目标:在一台机器上把本插件挂进 DSH,并确认它**真的在跑**。 > 关键前提:**先确认宿主版本,再选版本线**——选错线的唯一症状是「静默失效」。 ## 一、前置条件 | 项 | 要求 | | --- | --- | | Node | ≥ 20(`engines.node`);本机验证用 22.x | | pnpm | 11.x(`pnpm install` 会自动触发 `prepare: tsdown` 构建) | | DSH | 见下面的版本矩阵 | | 终端可用性 | 仅 v0.19.1 线需要额外放行 `node-pty` 原生构建(见 §五) | ### 1.1 宿主版本矩阵(先读这张表) | 版本线 | 分支 | 插件版本 | peer 声明 | 适用宿主 | | --- | --- | --- | --- | --- | | 旧宿主线 | `main` | 1.2.0 | `^0.1.5-rc.1` | DSH `0.1.5-rc.1+`(含 `0.1.5-rc.2`,即 **DSH Desktop 2.0.10** 内置版本) | | 新宿主线 | `sync/v0.24.1` | 1.3.0 | `^0.2.0-rc.1` | DSH `0.2.0-rc.1+` | **怎么查宿主版本**(扩展模式桌面版): ```bash # 内置的 dsh 版本 grep -m1 '"version"' "/Applications/DSH Desktop.app/Contents/Resources/app/node_modules/@deepseek-ai/dsh/package.json" # 或看 profile 里装的宿主包 grep -m1 -A2 '"@deepseek-ai/dsh"' ~/.dsh/profiles/desktop/package.json ``` **选线决策** ``` 宿主 ≥ 0.2.0-rc.1 ? ── 是 ──▶ sync/v0.24.1(1.3.0) └─ 否 ──▶ main(1.2.0) ``` > ⚠️ **peer 不匹配不会报错。** 宿主以 `semver.satisfies(host, peerRange, { includePrerelease: true })` 预检, > caret 跨 minor 判 false 后**整行静默禁用**:不加载、无日志、界面上「像没装」。 > 因此「装完没反应」的第一件事永远是核对宿主版本 ↔ peer 范围。 ## 二、安装方式(本 fork 未发布 npm 包) `npm view dsh-apes-sidebar` 返回 404 —— **本 fork 不在 npm 上**(README 里的 npm 徽章/命令是沿用上游文档)。 实际部署使用「本地源码 + `file:` 链接依赖」: ### 步骤 1:构建 ```bash cd <插件仓库绝对路径> git checkout main # 或 sync/v0.24.1(按宿主版本选) pnpm install # 会顺带跑 prepare: tsdown pnpm typecheck && pnpm build && pnpm test # 门禁三连 ``` 产物(`lib/`):`index.js` / `invariant.js`(host)+ `client.js` + 懒加载 chunk (`client-registry` / `client-editor` / `client-locale` / `client-mermaid` / `client-terminal`)+ `types/`。 ### 步骤 2:接进 profile 编辑 `~/.dsh/profiles//package.json`(桌面版为 `desktop`,网页版通常为 `web`): ```jsonc { "dependencies": { "dsh-apes-sidebar": "file:/绝对路径/dsh-apes-sidebar" // ← 必须是绝对路径 }, "dsh": { "profile": { "bundles": [ "…", "dsh-apes-sidebar" // ← 加入 bundle 栈 ] } } } ``` > 也可以在 profile 自己的 `cordis.patch.yml` 里手写挂载行(老方式)。**两种方式不要同时用**: > 会双挂载成两个 Node 半、两个侧边栏。包内自带的 `cordis.patch.yml` 是 `dsh.bundle.patch` 层, > 由官方 CLI 安装时自动追加 bundle,并带「聚合包双挂载退让」守卫。 ### 步骤 3:让 profile 重新安装依赖 ```bash cd ~/.dsh/profiles/ && pnpm install ``` **为什么必须重装**:pnpm 对 `file:` 依赖是**复制**语义(不是软链)。源码 `pnpm build` 之后, profile 的 `node_modules/dsh-apes-sidebar/lib` **仍是旧副本**——这就是「改了代码但界面没变」的头号原因。 DSH 启动时也会 reconcile profile 的 pnpm workspace,但不要假定它一定帮你刷新。 ### 步骤 4:完整重启 **⌘Q 完全退出 DSH,再重新启动**(不是关窗口)。client 半有热加载,但 host 半与依赖变更必须走完整重启。 ## 三、验收清单 重启后逐条核对(每条都对应一个可观察事实): - [ ] **右列只有一套侧边栏**、一个开合控件(不再出现自绘的第二套开关) - [ ] 原生 guide 里能看到本插件的 tab 芯片,且**带图标** - [ ] 三个信息层 tab 存在:**智能体 / 应用 / 画像**(order 在原生面板之后) - [ ] `apes:agents` 打开后:有主代理卡片;有子代理时列出直系子代理(标签 + 模式 + 运行态) - [ ] 打开一个 HTML 文件:**沙箱态下自包含 HTML 能正常渲染**(不再是 `forbidden`) - [ ] 打开「社区插件市场」:弹窗**完整盖在**本插件面板之上(面板不切弹窗角) - [ ] 页面左下角**没有**红色诊断条(有的话说明 client 生命周期某处抛错) - [ ] 开发者控制台**没有** `[dsh-apes-sidebar] … error` 前缀的错误 ## 四、网页 profile 与桌面 profile 的差异 | 项 | 桌面版(DSH Desktop) | 网页版 | | --- | --- | --- | | profile 目录 | `~/.dsh/profiles/desktop` | 通常 `~/.dsh/profiles/web` | | 外壳 | Electron 壳,有「扩展模式/兼容模式」与请求围栏 | 浏览器直连宿主端口 | | 预览 iframe | 受渲染器围栏约束(因此必须走 `srcDoc` 交付) | 无该围栏,但仍受路由 CSP/沙箱约束 | | 面板宿主层级 | 壳层会给 `#root` 打 content-viewport 标记 → 宿主挂进 `#root` | 无标记 → 宿主挂 `document.body` | | 刷新方式 | ⌘Q 完整退出再启动 | 硬刷新(Cmd/Ctrl+Shift+R) | ## 五、v0.19.1 线特有:放行 node-pty 原生构建 `main`(上游 v0.19.1 基线)在 `package.json` 中仍有 `node-pty` 依赖;pnpm 11 默认**拦截依赖的构建脚本**, 于是首次安装会失败或终端不可用: ```bash cd ~/.dsh/profiles/ pnpm approve-builds # 选中 node-pty,回车确认 pnpm rebuild node-pty # 必要时 ``` `sync/v0.24.1`(1.3.0)**不含** `node-pty`(终端交由宿主内置承担),无需此步。 (`main` 与 `sync/v0.24.1` 的 `node-pty` 引用数:1 / 0。) ## 六、切换与卸载 同一条线只能装一个(两条线都注册 `ctx.betterSidebar`,entry id 冲突,第二个被丢弃)。 仓库自带切换脚本: ```bash bash scripts/switch.sh --status # 只看当前是哪条线 bash scripts/switch.sh aps # 切到本 fork 线(本地 file: 安装) bash scripts/switch.sh upstream # 切回上游 dsh-better-sidebar bash scripts/switch.sh upstream 0.18.0 # 指定上游版本 bash scripts/switch.sh aps --profile web # 指定 profile ``` **完全卸载**:从 profile 的 `dependencies` 与 `dsh.profile.bundles` 中移除 `dsh-apes-sidebar`, `pnpm install`,⌘Q 完整重启。若曾手写过 `cordis.patch.yml` 挂载行,一并删除(否则会留下悬空 entry)。 > 若同时装了聚合包(如 `@linxin666/dsh-web-ui-all`)且它内部也挂载了本包, > 包内 bundle patch 的守卫会让**本行退让**;此时请确认聚合包在 bundle 栈中位于本行之前。 ## 七、变更后的重新部署 ```bash # 插件仓库 pnpm typecheck && pnpm build && pnpm test # profile cd ~/.dsh/profiles/ && pnpm install # ⌘Q 退出 DSH 再启动 ``` 改完代码**必须**走完这三步:产物构建非字节确定性,profile 的 `file:` 副本也不会自动跟随。