## 验证 DSH 插件真的可用(实战方法) > 本文从 dsh-agent-teams 插件(多智能体团队协作 + Web UI 活动面板)的完整验证历程蒸馏而来。 > 全部命令都真实执行过;每一层都踩过坑,坑已标注在对应步骤。原则:**不碰正在运行的实例,验证在独立 profile / 独立端口 / 临时目录上进行,测完清理**。 ### 验证金字塔总览 自底向上四层,每层通过再进下一层;任何一层失败都要先修再继续: 1. **离线**:双 program typecheck + 构建 + 冒烟脚本(纯逻辑、临时目录、自清理) 2. **组合**:`dsh --profile --dump-config` 验证 bundle 补丁能组合进配置树(不 boot、不碰实例) 3. **真实端到端**:独立 headless profile + 真实 LLM 任务 + 落盘/事件检查 4. **GUI**:独立 web 实例 + ego-browser 驱动真实浏览器(名册 → 路由 → DOM 探针 → 截图) --- ### 1. 离线验证 #### 1.1 双 program typecheck DSH 插件往往同时有 **host 侧**(Node:工具、路由)与**浏览器侧**(React 组件、Conversation Node)。两边会拉进互相冲突的类型声明(典型:host 侧 `dsh-session` 的 index 声明 `Context.sessions: SessionStore`,与浏览器 runtime 的 `ISessions` 同名冲突),**必须拆成两个独立 tsc program**: ```jsonc // tsconfig.json(host):include src,exclude ["src/client"] // tsconfig.client.json:extends ./tsconfig.json + jsx react-jsx + lib DOM + types [] // include ["src/client", "src/event-types.ts", "src/css-modules.d.ts"] ``` ```sh tsc -p tsconfig.json --noEmit && tsc -p tsconfig.client.json --noEmit # 两个都要 0 错误 ``` 坑(都真实踩过): - **`.ts` 文件不解析 JSX**:客户端入口含 JSX 必须命名为 `index.tsx`(`index.ts` 会把 `' expected`,且与 jsx 配置无关)。 - **`declare module` 合并需要目标模块先被加载**:`declare module '@deepseek-ai/dsh-session/types'` 扩展 `SessionEventMap` 前,该模块必须已作为模块存在于 program 中——在文件顶部加 `import type {} from '...'`(类型导入会加载模块声明,产物中被擦除)。 - **闭包内窄化失效**:`match.event.data.x` 在 `.map((m) => ...)` 回调里使用时,判别联合窄化不保留——先在守卫后提取 `const x = match.event.data.x` 再用。 - **类型链接目标**:`profiles/node_modules/@deepseek-ai/*` 的链接指向不稳定(staging 快照可能是旧构建,声明 `module 'cordis'` 而非 rescoped 的 `'@deepseek-ai/cordis'`)。开发时把 `node_modules/@deepseek-ai/` 直接链接到 **checkout 源码包的目录**(其 `lib/types` 是声明正确的构建);若 client 包 lib 过期(缺 `Context` 声明合并),优先链接到运行实例同版本的 staging 构建,或直接映射源码。 #### 1.2 构建(tsc + tsdown client bundle) ```jsonc // package.json scripts "build": "tsc -p tsconfig.json && tsc -p tsconfig.client.json && tsdown", "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.client.json --noEmit", "verify": "node scripts/verify.mjs" ``` - tsc 产出 `lib/`(host 可执行 ESM)与 `lib/types/`(声明) - `tsdown` 把 `lib/client/index.js` 打包成浏览器 bundle `lib/client.js`(协议:CJS closure-factory,`window.__ModuleLoader__.load({ id, factory })`;外部化平台模块 react / `@deepseek-ai/dsh-client-*`;CSS Modules 经 lightningcss 内联并注入 `