# 开发与验证 ## 质量门槛 - `npm run typecheck`:严格 TypeScript,包括 `exactOptionalPropertyTypes`。 - `npm test`:Vitest 单元、集成、生命周期、发布结构和回归测试。 - `npm run test:coverage`:宿主侧(包括 `src/browser-worker/**`)逐文件 statements/branches/functions/lines 全部 100%,任何单文件低于 100% 都失败。 - `npm run test:snapshot`:只读比较已评审的无密钥 DSH Tool catalog snapshot;更新必须显式执行 `test:snapshot:record` 并审阅差异。 - `npm run test:built`:先构建,再由普通 Node 按包名加载发布入口,检查无默认导出、真实 exports 和 MV3 发布结构。 - `npm run build`:DSH Host ESM、类型产物、lazy-CJS Web Client,以及 MV3 扩展 bundles。 - `npm pack --dry-run`:检查发布清单只包含运行所需文件,并确认 `fflate`、`ws` 作为 bundled dependencies 进入离线 tarball。 - `npm run check`:串行执行上述全部本地可运行门禁。 - Cordis lifecycle:通过真实 `Context`、`ToolRuntime` 和 plugin fiber 验证注册、卸载、tool 清理与端口释放。 - DSH CLI smoke:新 profile 安装 tarball 后执行 `--dump-config`。当前托管环境无法完成的项目必须明确标记 `NOT RUN`。 - 兼容基线:开发依赖与 peer dependency 必须精确锁定 DSH `0.1.2-rc.1`;Session 历史只能通过公开的 `snapshotEvents()` 和 `eventAt()` 读取,不得依赖私有事件数组。 Chrome MV3 代码运行在浏览器拥有的 service worker、content script 和 popup realm 中,Harness 设置页运行在 React Web Client realm。官方 DSH 仓库也会把环境专属浏览器源码从宿主 V8 逐文件门禁中排除。本项目的逐文件 100% 门禁覆盖 Host(含 `src/settings/**`),不把 `src/extension/**` 或 `src/client/**` 计入宿主统计;Client 由 JSDOM 组件/Slot 组合测试和发布 bundle 静态检查覆盖,扩展纯逻辑由 JSDOM/Node 用例覆盖,真实浏览器行为归属 Chrome E2E 车道。排除项不能被计入“100% 宿主覆盖率”。 ## 测试分层 1. 纯逻辑:协议解析、pending、配置、artifact、DOM ref、Chrome 跨平台定位、bundle receipt/hash、敏感数据识别/脱敏。 2. 确定性状态机:注入受控 WebSocket server/socket,覆盖启动失败、认证顺序、心跳、发送竞态和异常清理。 3. 模拟通信:真实 Node WebSocket client 模拟扩展,与真实 bridge 完成双向 HMAC 配对、乱序 result、timeout、abort 和断连。 4. DSH/Cordis:真实 plugin fiber、ToolRuntime、AgentLoop、SubagentRuntime、spawn provider、TokenMeter、ApprovalService 审计对、24 个 `defineTool` 契约以及父/Worker 双目录无密钥 schema snapshot。 5. Web Client:真实 Slot/Locale 组合与 JSDOM 组件,覆盖状态响应校验、下载入口、配对参数复制、错误/刷新及卸载。 6. 构建产物:普通 Node 包自引用、Host/Client exports、lazy-CJS factory、manifest 和扩展 bundle 安全结构。 7. DOM runtime:JSDOM fixture 覆盖普通输入、密码预填、disabled、动态页面无关更新、目标语义变化 stale ref、原子名称点击、重复正文去噪,以及 CSS/XPath、开放 Shadow Root 与动态属性降级。 8. 真实 Chrome:覆盖启动检测、审批后本地部署、Chrome 自身 Load unpacked 确认、content script、service worker 重启、LNA 和 `chrome.debugger`。 9. Browser Worker:真实父 Agent 委派、fresh child、低层工具调用、紧凑 structured output、单步结果淘汰、软/硬阈值、未知工具/无进展熔断和 content-free rollover checkpoint。 10. Artifact delivery:opaque ID 所有权、父 Session grant、session-cwd containment、traversal/symlink/覆盖阻断、原子发布、collision rename、partial 状态及 delivery-only retry。 ## 用例编写规则 - 测试文件使用 `*.spec.ts`;共享 harness 放在普通 helper 文件,禁止从另一份 spec 导入 fixture。 - 优先断言可观察行为和外部状态,不断言私有实现细节。 - 除 Chrome、网络、时钟和文件系统竞态等边界外,优先使用真实实现。 - 每个资源由用例创建并在 `afterEach`/`finally` 中释放;禁止依赖测试执行顺序。 - 每个已修复的竞态、错误路径或契约回归必须保留永久用例。 - `v8 ignore` 只能用于无法确定性制造的外部竞态或类型穷尽分支,且必须在同一处写明具体原因。 - Snapshot 默认只读;没有人工审阅时不得自动刷新基线。 ## 云/内置浏览器限制 部分托管浏览器只暴露远程 CDP 页面控制,不提供“加载本地未打包扩展”能力,也无法访问工作区进程的 `127.0.0.1`。这种环境只能完成前三层验证;真实扩展安装必须在可加载 unpacked extension 且与 DSH bridge 位于同一台主机的 Chrome 中执行。测试报告必须把这项标为 `NOT RUN`,不能用普通页面脚本冒充扩展 E2E。 ## 新增 action 清单 新增浏览器能力时必须同步: 1. `src/protocol/actions.ts` 的白名单。 2. DSH tool 参数与输出 schema。 3. service worker command router。 4. content/network runtime(如适用)。 5. 协议、模拟通信和真实 Chrome 用例。 不要加入任意 JavaScript 求值或任意 CDP 透传作为快捷方式。