# 布局与交互修正验证(2026-10-25) 开发、构建与测试目录:`D:\Project\dsh-workspace-graph`。修改保留在现有功能分支 `feature/气泡手感优化`,本地 `dist/client.js` 已重新构建。 ## 七项要求的结果 | 要求 | 实现与验证 | | --- | --- | | 连线与气泡正确连接 | 共享圆心/半径与自定义 RopeEdge,端点裁切到实际圆周。浏览器在缩放和拖动中测量屏幕误差小于 0.001px;原生宿主也检查圆形几何与端点误差 ≤ 2px。 | | 树状网状布局、向外展开 | 按真实工作区和分支关系分配径向扇区,多棵树分开放置。默认坐标由完整目录和稳定 ID 产生;小气泡从父圆周外侧展开。隐藏节点和新增节点继承最近已移动祖先的位移。重排、100 个宽分支、循环/缺失父节点及首次展开回归通过。 | | 并行工作区域完整显示 | 收集全部 mainView 当前会话;当前、running、pending 会话越过折叠、分页与筛选,并保留祖先链。工作区聚合标识;待回应与运行仍是不同状态。单元、演示并行及真实原生双 mainView 引用验证通过。 | | Ctrl 自由拖动且保留碰撞 | Ctrl 只移动被抓节点,其他节点仅因接触避让;支持拖动中切换和失焦清理。同组、跨组链条、扫掠碰撞、按键转换与真实原生输入通过。 | | 碰撞体增加 25% | 接触距离乘 1.25,画面圆球不放大;拖动有效比例 1.075,静止比例 1.25。所有尺寸与空间索引一致,拖动中不再暂停组内碰撞。 | | 软绳、停止渐硬及部分恢复 | 沿真实边逐级传力,近端/远端存在滞后。停止输入约 120ms 或松手后,在约 1.2 秒渐硬;按 80% 原相对向量 + 20% 停止姿态形成目标,保留整体平移。碰撞优先,Ctrl 终态成为新基准。30/60/120Hz 及密集节点最终休眠通过。 | | 启动恢复默认位置 | Repository 运行内保存位置和视角;重新挂载面板保留,刷新/新应用实例重置。旧版持久位置和视角忽略,主题/概括/置顶/使用记录/筛选保留。浏览器迁移、双窗口及真实 DSH 页面重启通过。 | ## 检查与产物 - `npm test`:73/73;新增核心用例均先确认失败,再实现通过。原有测试中有关深重叠、向上固定端点、单当前会话和跨重启坐标的断言随新要求更新。 - `npm run typecheck`、`npm run build`、`git diff --check`:通过。 - `npm run test:browser`:10 组主 UI 回归通过,包括主题、手动概括、筛选、归档、损坏存储和重新载入。 - `node tests/rope-edge-browser.mjs`:SVG 端点测量;`tests/ctrl-drag-browser.mjs`、`tests/flex-drag-browser.mjs`:两种拖动与软硬恢复。 - `tests/runtime-layout-browser.mjs`:并行当前标识、面板重挂载、启动默认、旧存储迁移、另一个窗口在拖动中更新设置。 - `tests/hidden-layout-browser.mjs`:折叠父工作区移动后,首次展开的完整分支落在平移后的外向目标。 - `tests/hierarchy-browser.mjs`、`tests/interaction-regressions.mjs`、`tests/summary-edge-browser.mjs`:层级、来源、视角稳定和边缘聚焦。 - `tests/lifecycle-browser.mjs`:键盘展开/收起、活动物理时卸载后的 RAF/定时器清零、重新进入后静止 RAF 停止。 - `npm run test:native`:隔离 DSH_HOME,真实宿主动态加载、双 mainView 引用快照、嵌套工作区、重命名、新会话导航、空白当前会话保留、Ctrl 拖动及重载默认布局。 界面测试使用系统 Edge,无头模式,`BROWSER_CHANNEL=msedge`;主回归设置 `WG_SKIP_VIDEO=1`,提供截图和数值,没有录屏。日志与新增截图在 `artifacts/layout-interaction/`,主 UI 截图在 `artifacts/bubbles/`,原生截图在 `artifacts/native-integration.png`。测试数据全部在项目 artifacts 的独立 DSH_HOME 中。 ## 性能样本 i7-13650HX、20 逻辑核心、Windows、Node 24.21.0、Edge 156.0.4314.42、1440×1000 无头浏览器;以下是本机样本,不作为其他设备的保证。 | 可见节点 | 拖动帧间隔平均 | 拖动 P95 | 展开 P95 | | --- | ---: | ---: | ---: | | 10 | 6.06ms | 6.5ms | 6.6ms | | 50 | 6.11ms | 6.3ms | 12.1ms | | 100 | 8.45ms | 12.3ms | 12.2ms | 三组均发生实际运动、最终画面稳定、可见圆形重叠 0px、页面错误 0。完整数据:`artifacts/browser-performance.json`。纯物理压力测试另存 `artifacts/physics-performance.json`,不将其计算时间当成完整 UI 帧时间。 ## 独立审查与实施取舍 一次独立只读审查发现 3 个 Important 问题,无 Critical/Minor。隐藏节点位移、多窗口运行补丁误报冲突、自由碰撞间接牵引均新增失败测试后修复,完整单元和界面回归已重跑。 - 遵从 AGENTS.md,在规范目录现有功能分支实施,未额外创建工作树。原有改动保留。 - 使用现有时间步进位置弹簧,没有新增物理依赖。极密星形的绳长若与碰撞不可同时满足,允许延长松绳以结束持续模拟。 - 碰撞扩大和圆周起点覆盖旧的浅重叠/中心展开规则。纯垂直 SVG 的包围盒宽度可为零,因此测试等待真实 path 并测量端点,不以包围盒判定可见。 - 运行位置不再跨窗口同步;持久设置仍有修订冲突保护。布局只在本次运行保留。 ## 验证边界 宿主声明 `retainedBy` 是 Client 本地计数,不能把本窗口 mainView 集合说成其他窗口的焦点。原生双当前验证使用测试专用客户端,通过公开 Session API 创建真实空会话并持有 mainView 引用;该夹具不进入发布包。没有执行真实模型并行运行、取消、失败或断线重连。 原生空会话没有 completed turn,宿主拒绝 fork;因此原生分支创建未验证,来源关系由适配器单元与完整层级浏览器夹具验证。初始浏览器基线受沙箱 Edge 管道限制未取到同机旧版帧样本,后续界面测试以批准的隔离浏览器进程完成,不声称相对旧版的性能提升。 本轮交付为本地源码、构建和验证结果;没有合并、提交、发布或覆盖真实用户的已安装插件。