# dsh-roam 项目工作手册 本文件是代理进入本仓库后的操作入口,面向代码修改、测试、审查和发布准备。它只记录项目当前规则;复杂角色流程见 `.agents/court/`,面向用户的功能说明见 `README.md`。 ## 先确认目标与现状 `dsh-roam` 把电脑上的 DeepSeek Harness 会话带到手机浏览器:扫码配对、手机新建或继续任务,不复制整个桌面 IDE。 开始工作前: 1. 读取用户目标、本文件和任务涉及的角色卡,再读相关源码与测试。 2. 运行 `git status --short`、`git log -5 --oneline`,确认当前分支、已有修改和文件所有权。 3. 保留用户已有修改。不要 `reset --hard`、`clean -fd`、覆盖整文件,或把任务变成无关重构。 4. 纯问答、解释、只读分析直接回答,不创建项目任务,也不为了流程调用子代理。 5. 信息不足时,最多问一个会改变验收的问题;其余合理假设写进任务说明。用户明确指定 UI 方向时,先落实该方向,不再反复提供备选方案。 ## 产品与代码边界 - `main` 只做手机浏览器客户端;不恢复 AI-HUB App、移动 API、设备凭据、设备台账或 `dsh-mobile-plugin` 依赖。 - AI-HUB 兼容线固定在 `0.3.1` / `legacy/aihub`,只接受安全修复。 - 手机页默认新建首页;最近会话通过左上角左侧抽屉访问;聊天页有独立头部、可见返回键和底部安全区。 - 手机与面板不加载 CDN、外部字体、外部图片或 iframe;品牌只读 `/brand-logo/*`。 - 不为了“功能齐全”加入系统通知、语音、预览面板、文件管理或终端。新需求先确认它属于手机任务闭环。 ### 源码地图 | 路径 | 当前职责 | 修改时重点 | | --- | --- | --- | | `src/index.js` | 宿主装配、回环设置路由、状态快照 | 路由字段完整、同源与回环边界 | | `src/client.js` | 「连接手机」设置面板,经典浏览器脚本 | 不得被 tsc 编译;不得顶层 `import` / `export` | | `src/mobile/` | 手机主界面,原生 HTML / CSS / ESM | 不经 tsc,原样复制;集中文案只在 `copy.js` | | `src/bridge/lan-mobile-bridge.ts` | 配对、Cookie、RPC / SSE、会话投影、附件、审批、隧道 | 不改变既有协议词汇与安全边界 | | `src/bridge/lan-mobile-static.ts` | 同源静态资源白名单服务 | 授权后读取、MIME、ETag、路径拒绝 | | `src/bridge/lan-mobile-pages.ts` | 重连与连接密码页面 | 不承载手机主界面 | | `src/bridge/*settings*`、`pairing-pin-store.ts`、`acme-certificate.ts` | 设置、PIN 与证书 | 原子写入、迁移、私钥权限、失败可恢复 | | `scripts/copy-browser-client.mjs` | 复制浏览器资源 | 清单与服务端白名单一致 | | `test/` | Node 测试、真实 bridge / 假 Host、Chrome 验收 | 测试发布产物,不能只断言源码字符串 | `src/` 是唯一源码。`lib/` 只由构建生成,不提交、不手改。 ## 默认工作流:先合同,再实现,再验收 ### 1. 判断任务规模 | 类型 | 默认做法 | 必须验收 | | --- | --- | --- | | 说明、分析、单文件文案或小修正 | 直接处理,不走完整编制 | 相关检查与差异审查 | | 明确的局部 bug / 面板调整(≤2 个模块) | 一个模块 owner 实现,测试独立验收 | 相关回归 + 全量测试;浏览器行为需要真实 DOM | | 跨模块功能、协议 / 鉴权 / 证书、数据格式、构建发布、手机交互重构 | 按 `.agents/court/COURT.md` 常规流程,冻结契约后派发 | 端到端回归、全量测试、打包与实际浏览器;门下省审 diff | 只有任务可独立拆分且并行收益明显时才调用多个代理。复杂流程的角色名是职责边界,不是必须凑齐的人数;小任务不为流程图付出重复审查成本。 ### 2. 冻结任务合同 修改前写清:目标、现状证据、影响文件、保留的兼容行为、可测试的完成条件。 - 每个并行任务只有一个明确的模块 owner;同一文件不能同时派给多人。 - `src/mobile/copy.js` 的文案归礼部;其余手机页面归工部;`test/**` 归刑部;`AGENTS.md` 与 `.agents/court/**` 归吏部。 - 跨文件共享状态(history、overlay、会话 owner、请求序号、投影)先设计唯一事实来源,再写 UI,避免不同组件各自猜状态。 - 不添加只为绕过旧问题的开关、平行实现、备份文件或过时兼容分支。需要改结构时重写任务涉及的部分,保持当前唯一正确状态。 - 注释解释“为什么”和不可从代码读出的业务约束;命名表达“做什么”。不留注释掉的旧代码、手工备份或临时调试文件。 ### 3. 实现与协作纪律 - 主代理负责接口契约、集成与最终交付;子代理只修改自己的文件范围,不擅自提交、推送、改全局 DSH 配置或写真实用户数据。 - 任务板只用于实际多代理任务;根卡记录目标与验收,子卡记录 owner / 文件 / 依赖 / 验证。不要为同一工作重复创建多套任务记录。 - 共享 `lib/` 的 `pnpm build`、`pnpm test`、`npm pack` 不在同一工作区并行运行;它先清空再生成,并行会造成旧产物与“偶发失败”。 - 并行代理只编写独立源码或独立测试;接线、构建、全量测试与 diff 审查在集成后串行执行。 - 浏览器模块与 Node 测试引用 `lib/`,不得绕过构建直接验证 `src/` 并声称发布产物正确。 - 没有证据时标明“未验证”;不能把旧构建、其他版本或其他测试文件的通过结果当作当前结果。 ## 安全与状态红线 - `/phone-bridge/*` 只接受回环请求并校验同源;公网/转发头/固定公网域名按规则校验 6 位连接密码,不能按 Host 或来源 IP 降级。 - 配对令牌一次性且限时;浏览器只接受服务端签发的 Cookie。客户端提供的 Cookie 不得被提升为会话。 - 浏览器会话仅存内存,重启后需重新扫码。设备可见性只显示本次运行中的配对会话;无活动不等于断开,不代表物理设备数或完整历史。 - 设置与 PIN 原子写入;修改连接密码立即吊销浏览器会话。证书只为固定公网域名签发,私钥权限按 Windows ACL 规则收紧。 - 不在日志、测试、截图或提交中放 Cookie、令牌、密码、私钥或真实用户数据。静态资源仅在授权后按白名单提供,不能读任意磁盘路径。 - 新网络能力优先复用现有 Host / bridge 协议;不要绕过同源、权限审批、附件归属或请求大小限制。 - 默认数据目录是 `%USERPROFILE%\.dsh\dsh-roam`(`DSH_HOME` 可覆盖),真实用户数据不用于测试;测试使用临时目录。 ## 构建与验证 在仓库根目录运行;Windows + pnpm 12,Node ≥22.19。 ```bash pnpm install --frozen-lockfile pnpm build # 清空 lib,编译桥接并原样复制浏览器静态资源 pnpm test # 先构建,再运行全部 Node / Vitest pnpm test:browser # 真实 Chrome / Edge 移动交互验收 node .agents/court/render.mjs --check npm pack --dry-run ``` - `tsconfig.json` 必须排除 `src/client.js` 与 `src/mobile/**`;`package.json.files` 必须包含 `lib/mobile/`。 - 新行为补测试;修 bug 先有能复现的失败,再验证转绿。禁止 `.skip`、`.only`、空断言、删除或放宽断言来掩盖回归。 - 只读工具、类型检查或 HTML 字符串断言不能证明真实 UI 行为。导航、弹层、键盘、流式 DOM、会话切换等必须跑真实浏览器测试。 - Chrome 用 `playwright-core` 驱动已安装浏览器,不自动下载;可用 `DSH_MOBILE_CHROME_PATH` 指定路径。缺依赖或浏览器默认明确 SKIP,`DSH_MOBILE_BROWSER_REQUIRED=1` 强制失败。 - 浏览器截图默认在系统临时目录,可用 `DSH_MOBILE_UI_ARTIFACTS` 覆盖;`test/browser/artifacts/` 只存失败产物,不提交。 - 至少检查 320 / 360px 无横向滚动、44px 主触控目标、键盘与焦点、长短文案和深浅色。Chrome 移动视口不等于实体 Android / iOS;未真机或真实 Host 验证必须明确写出。 - 不在测试里真实启动 cloudflared、ssh、Let's Encrypt 或访问真实用户配置。 ### 完成标准 交付前按顺序串行确认: 1. 相关回归和全量 `pnpm test` 全绿。 2. 涉及浏览器行为时 `pnpm test:browser` 全绿。 3. 静态模块全部 `node --check` 通过;`src/client.js`、`src/mobile/` 与构建产物字节一致。 4. `npm pack --dry-run` 包含所需资源,未混入调试文件。 5. `git diff --check`、`git status --short` 和最终 diff 已审查;无越界改动、死代码、临时文件。 6. 报告实际命令、通过数量、剩余风险。不能写“应该可以”或把 SKIP 写成通过。 ## 提交、发布与回滚 - 本地提交只有在用户明确要求或授权后执行;提交前检查变更边界并全量验证。提交信息用简洁的 `type(scope): summary`,说明实际变化,不写无关版本宣传。 - 推送、打标签、npm publish、GitHub Release、修改全局 DSH 配置、安装/更新实际插件,分别需要明确授权。用户说“提交”不自动等于推送或发布。 - 发布按 `RELEASING.md` 执行:版本、CHANGELOG、发布文档、安装说明一致;必须完成真实配对,涉及公网时还要验证公网与 PIN。 - 回滚优先精确反向本次 hunks / 删除本次新增文件,不 reset、不清除他人改动、不清设置、Cookie、证书或用户数据。 - `main` 只接受快进;已推送提交与已发布标签不改写、不删除、不强制推送。 ## 文档维护 - 用户文档使用中文,写清能做什么、如何使用、数据在哪和限制;错误提示写“发生了什么 + 用户能做什么”。 - 功能、测试数字和已知边界随当前实现更新,不保留过时状态、重复段落或未经证实的平台支持。 - `AGENTS.md` 只保留跨任务长期有效的规则。临时实现细节、一次性的 bug 经过和角色扮演说明不写入;新反复出现的问题才沉淀到本文件或相应角色卡。 - 修改源码地图、角色辖区或构建规则时,同步 `.agents/court/COURT.md`、`roster.json` 和相应角色卡,并跑 `node .agents/court/render.mjs --check`。