chore: establish YCode replication baseline and TODO

This commit is contained in:
xiaohan.yuan committed 2026-10-17 02:43:49 +08:00
commit 6dc59f89ba
1118 files changed
+196002

No files matched your search

+165
View File
@@ -0,0 +1,165 @@
# SOP:Ygent 真实桌面 WebView2 调试与渲染采集
## 隔离动态链路验收
调试构建支持 `scripts/ygent-debug.ps1 -ReuseFrontend -Port 9336 -DataDirectory <绝对路径>`。
独立SQLite和托管项目目录位于该目录;进程变量为YGENT_DEBUG_DATA_DIR,脚本退出恢复原环境,发布构建忽略该变量。安装实例正在执行任务时,可用 `-ReuseFrontend`、独立数据目录与空闲端口并行启动调试实例,不能停止安装实例或共享其数据目录。脚本拒绝重复调试实例与正常数据目录;完成后只关闭本次测试 PID 和测试服务,不用测试库覆盖正常库。
可用本机受控SSE验证真实Rust/Tauri IPC/WebView2并记录DOM时间线。该响应属于测试数据,结果仅表示YG端到端通过,不能称为WB或真实模型对照通过。序列见[动态清单](ygent-chat-interaction-parity.md)。
开发句柄window.__yg包含真实chat/session/settings/channel store和flushChatWrites。隔离测试使用同一运行时句柄;Vite HMR带时间戳模块与不带时间戳的动态import可能产生第二套store,不能误当当前UI。普通采集仍只读,不调用send/abort或修改设置。
辅助回归:`pnpm check:chat`;后端:`cargo test --lib --manifest-path src-tauri/Cargo.toml`。不代替原生验收。
### 原生普通回合的刷新恢复
1. 用真实 `agent_live` 读取普通与协作运行,包括启动预留、冻结模型和原用户消息;`collaboration_live`只覆盖协作,空数组不代表所有工作停止。
2. 只读采集运行requestId、会话、最后持久消息ID与DOM。页面刷新后核对同一requestId、原正文前缀、工具详情及pending授权身份,等待真实新增量;刷新不是重新发送。
3. `agent_replay`返回有序快照及水位,思考活动不进入持久历史。宿主在页面不在场时继续保存正文/工具,页面以hostRunId和稳定块键对齐持久行,不重复写入。
4. 完成/取消后核对真实终态、消息不重复、工具消息ID及展开作用域保持;停止准确绑定requestId。程序退出再启动仅标中断,不能把刷新重接理解为自动重放副作用。
5. 实际员工“继续”同时核对team_user_continuations、原team_dispatches/messageId与当前runId、当前合同版本及经理结果路由;不要用普通手动回合绕过派发。测试不得给正在执行的正常库注入事件或直接SQL改状态。
适用环境:Windows、Tauri 2、WebView2、Node 22+。默认 CDP 端口 9335,前端端口 1420。
本流程连接真实桌面窗口,使用真实 Rust IPC 和数据库,不依赖 computer-use、模拟 IPC 或 fixture。
已于 2026-10-08 在本机验证:WebView2 154.0.4258.62、CDP 9335 回环监听、视口 1335×916、DPR 1;恢复真实会话 5 的 829 条消息,并成功生成 DOM/样式 JSON 与原生截图。Rust `cargo build --no-default-features` 通过。
## 1. 启动前检查
在项目根目录执行。常规同数据调试需保存输入框草稿并退出旧 Ygent;安装实例正在工作时,改用上方独立数据目录方式,禁止为验收停止它。
旧实例启动后不能补开调试端口;如果由 `pnpm tauri dev` 启动,也结束旧开发终端中的命令。
```powershell
Get-Process ygent -ErrorAction SilentlyContinue
Get-NetTCPConnection -LocalPort 9335 -State Listen -ErrorAction SilentlyContinue
```
启动脚本遇到旧实例或占用端口会报错,不会自动结束其他进程。
## 2. 调试模式运行
常规开发(编译 Rust、启动 Vite、打开桌面窗口,终端保持运行):
```powershell
pnpm debug:desktop
# 或指定其他空闲端口
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/ygent-debug.ps1 -Port 9336
```
如果 localhost:1420 的 Vite 已经运行且已有最新调试版可执行文件:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/ygent-debug.ps1 -ReuseFrontend
```
复用模式不会重新编译 Rust;修改 Rust 后先 `cargo build --manifest-path src-tauri/Cargo.toml`,再启动隔离实例,或在无运行任务时使用常规开发模式。
脚本仅对启动子进程设置 `YGENT_DEBUG_PORT=9335`,随后恢复当前终端原值,不使用 setx 或注册表。
Windows debug 构建读取此变量,通过 Tauri 的 `additional_browser_args` 传入 `--remote-debugging-port`,保留默认浏览器参数;release 构建不启用此入口。
本机实测仅设置 `WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS` 未开放端口,不能把环境变量设置成功视为已连通。
机制参考:[Tauri 参数接口](https://docs.rs/tauri/latest/tauri/webview/struct.WebviewWindowBuilder.html#method.additional_browser_args)、[Microsoft WebView2 调试说明](https://learn.microsoft.com/en-us/microsoft-edge/webview2/how-to/debug-visual-studio-code)。
## 3. 确认连接的是原生窗口
```powershell
Invoke-RestMethod http://127.0.0.1:9335/json/version | Select-Object Browser, 'Protocol-Version'
Invoke-RestMethod http://127.0.0.1:9335/json/list | Select-Object id, title, type
Get-NetTCPConnection -LocalPort 9335 -State Listen | Select-Object LocalAddress, OwningProcess
```
验收条件:端口仅回环监听,目标为 localhost:1420 的 page,页面同时具有 `window.__TAURI_INTERNALS__` 和开发调试句柄 `window.__yg`。
仅有 localhost URL 不足以证明是原生窗口;采集脚本会检查两项句柄,不符合时拒绝采集。
9334 的独立 Edge 参照页面与此原生端口不同,不能混用验收结果。
## 4. 采集真实渲染
打开待验收会话,设置对应字号,定位到目标消息,展开待比对的过程行,等内容稳定后执行:
```powershell
$ygSopCapture = Join-Path $env:USERPROFILE ('.ygent\imports\ygent-debug-' + (Get-Date -Format 'yyyyMMdd-HHmmss-fff'))
node scripts/ygent-cdp.mjs "$ygSopCapture" 9335
$ygSopSnapshot = Get-Content (Join-Path $ygSopCapture 'dom-styles.json') -Raw -Encoding utf8 | ConvertFrom-Json
$ygSopSnapshot.viewport
$ygSopSnapshot.state
$ygSopSnapshot.samples | Where-Object selector -eq '.thread-content' | ConvertTo-Json -Depth 8
```
输出 `connected: true`、`runtime: native-tauri-webview2`,保存:
| 文件 | 内容 |
| --- | --- |
| dom-styles.json | DOM/HTML、最终计算样式、元素矩形、滚动尺寸、视口/DPR、活动会话与消息数量摘要 |
| ygent.png | 真实 WebView 当前视口截图 |
采集不读取 cookies、存储、密钥或完整 store,不改动页面状态。正文和截图仍包含真实会话,应保存在上述私有目录。
DOM 与截图先后采集,不是原子快照;流式生成期间需注明时间差。
## 5. 深入调试与对标
可在 Edge 的 `edge://inspect` 配置 `localhost:9335`,选择 Ygent page 的 inspect,使用 Elements、Computed、Console、Sources、Network。
Console 中只读查询示例:
```javascript
getComputedStyle(document.querySelector('.thread-content')).maxWidth
document.querySelector('.thread-content').getBoundingClientRect().toJSON()
window.__yg.useSessionStore.getState().activeId
window.__yg.useChatStore.getState().messages.length
```
读取不存在的元素前先检查选择器命中情况;新建任务页面可能没有对话节点。
对标 WorkBuddy 参照 [WorkBuddy CDP SOP](workbuddy-cdp.md)。记录同一会话、字号档位、窗口/视口、DPR、滚动位置及展开状态,先比较结构和计算样式,再检查截图。
不使用 Emulation 修改原生视口来代替真实窗口尺寸,不把模拟 IPC 的页面当作原生验收。
## 6. 退出调试与排错
- 退出 Ygent,再用 `pnpm tauri dev` 普通启动即可关闭本次 CDP。若终端外部本来设置了 `YGENT_DEBUG_PORT`,先移除该变量。
- 端口不响应:检查是否启动了旧实例、WebView2 是否继承启动参数、可执行文件是否存在;不要仅重启 Vite。
- 无目标:确认 Vite 1420 和原生窗口均已加载;本采集脚本针对开发页面,不针对安装版 tauri.localhost。
- 缺少 `__yg`:确认是 Vite 开发版;缺少 Tauri 句柄:确认没有连到独立浏览器。
- 采集无对话节点:先在真实窗口打开目标任务,再采集,不注入数据掩盖问题。
## 7. 对话路径 → 右侧工作台(2026-10-10)
- 对话正文中已识别的目录/文件路径默认在右侧工作台打开,支持点击、Enter 和空格;目录直接定位,文件复用已有标签(统一 Windows 路径分隔符)。收起后再次点击会重新展开。
- 目录浏览、文本与 Markdown 预览沿用当前对话实际工作目录边界,不因项目导航切换扩大范围。目录外路径显示读取拒绝;二进制文件显示不支持文本预览;均不自动调用系统应用。工作台“系统打开”是显式外部入口,目录标签打开当前浏览目录。
- 会话切换清除待打开路径,工作台标签仍按会话挂载隔离,不向新会话重放上个会话的请求。未新增图片/PDF/Office 预览;文本仍限制前 1 MB。
- 本机真实 Tauri WebView2、CDP 9336、视口 1335×916、DPR 1 验证通过:目录定位、两级返回到根目录、JSON 实际内容、重复点击及目录条目/正文路径共用文件标签、Markdown 渲染/源码、Enter/空格、收起重开、外部目录/文件拒绝、二进制预览错误、错误后恢复和跨会话隔离。采集了实际 DOM、计算样式及矩形:工作台 x=809.015625、y=46、宽=525.984375、高=870,display=flex。
- 验收使用独立测试数据库,通过真实宿主 IPC 持久化受控路径消息,再操作真实 DOM;没有模拟/替换 IPC,没有验证真实模型流式输出。截图保存在用户私有目录 `~/.ygent/path-workbench-smoke.png`。未改动已安装客户端,未进行 Mac/Linux 验收,未触发系统打开按钮。
- 类型检查 `node node_modules/typescript/bin/tsc --noEmit` 和 `node node_modules/vite/bin/vite.js build` 通过;构建仍提示大 chunk。本机 pnpm 入口遇到 esbuild 构建脚本审批错误,因此直接执行已安装的本地工具,未调整依赖审批设置。
- 同时运行已安装客户端时,独立调试窗口首次启动出现 WebView2 HRESULT 0x8007139F;为调试子进程临时指定独立 `WEBVIEW2_USER_DATA_FOLDER` 后成功,不修改系统环境变量或发布配置。
## 并行隔离验收的 WebView2 配置(2026-10-10)
调试构建同时设置 `YGENT_DEBUG_PORT` 与绝对路径 `YGENT_DEBUG_DATA_DIR` 时,主界面 WebView2 使用该数据目录下的 `debug-main-webview`。子浏览器仍按项目/对话使用原有独立 profile;发布构建不启用这个分支。
不要用 `WEBVIEW2_USER_DATA_FOLDER` 隔离含内置浏览器的整进程:它会覆盖子 WebView 的目录,主界面与浏览器使用不同启动参数时,WebView2 可能报 `0x8007139F`。本轮已在真实子视图创建时复现。仅修改当前启动命令的环境,不永久设置系统变量。
需要与用户运行窗口并行验收时,使用独立数据目录和未占用端口;回归脚本先校验 `activity_test_mode=native-isolated`。窗口尺寸以实际 DOM 为准;Win32 缩放/恢复前校验窗口 PID、标题和句柄,只操作验收进程。测试结束关闭自身标签、回环服务和进程,保留用户窗口。
## 编译缓存与磁盘占用
开发与测试共用 `Cargo.toml` 的 dev 配置:`debug = 1`、`incremental = false`,第三方依赖 `debug = 0`。保留 Ygent 自身回溯的文件/行号,不保留完整变量调试信息;需要调试第三方 Rust 依赖时临时启用其符号。WebView2 的 CDP、DOM 与流式调试不受影响。release 配置独立。
关闭增量缓存以减少长期磁盘占用,代价是 Rust 代码重编译更慢;依赖编译产物仍由 Cargo 复用。切换 profile 设置后的首次编译会重建受影响的依赖,不代表每次都全量编译。
旧缓存不会随配置变更自动删除。无 cargo/rustc 构建进程时,可清理 `src-tauri/target/debug/` 下的 `incremental`、`deps`、`build`、`.fingerprint`;这些是可重建的中间文件。保留顶部可执行文件、运行资源、sidecar 和 release 分发产物。清理后首次开发编译和测试须重建依赖。若运行中或正在构建,先停止对应任务再清理,不能一边编译一边删除。
## 长历史对话打开卡顿(2026-10-13)
用户反馈从团队打开成员执行对话时整个页面短暂无响应。真实正常库的Rust成员对话约2,000条消息、正文/工具/参数合计约600万字符。通过9335的真实WebView2连接,在执行同一 `openSession` → `showView('chat')` 路径前开启CDP `Profiler.enable/start`,打开后等待首轮渲染,再 `Profiler.stop` 保存CPU profile;同时使用 `PerformanceObserver` 记录 `longtask`。这些探针仅导航、读取和测量,不发送模型消息、替换IPC或注入消息数据。
诊断必须分别记录会话/消息IPC等待、历史合并、Markdown解析、首次布局及滚动恢复,不能把Promise等待当成JavaScript计算。此次既捕捉到首次Markdown/布局的长任务,也出现过打开等待22秒而渲染线程主要空闲的情况。相关同步IPC在原生窗口线程取数据库锁和读取,不适合继续放在UI线程;具体22秒内的持锁方未捕获,不能宣称已经定位到某个后台工具。
实现:
- `HistoryTurn` 仅在历史接近滚动视口时首次挂载正式 `TurnBlock`,挂载后持续保留,滚动离开不重置手动展开。当前生成、未处理问题/授权、搜索、分享和明确定位的历史立即挂载。原始消息仍完整保留,历史不截断、不按会话特殊处理。
- 共用Markdown高亮转换器的语言登记,避免每个段落重复注册全部语言;正文、代码、公式及工具仍使用原组件。已显现历史通过content-visibility跳过离屏布局和绘制。
- 真实消息行按ID/运行建立索引,合并活跃协作和历史不逐消息扫描整个历史。恢复滚动保存消息锚点及相对偏移,历史挂载改变高度时按真实跟随状态处理,用户上滚不会被强行拉回底部。
- 会话/消息读取、团队成员/工作台、协作列表及任务实际运行查询改用 `spawn_blocking`;保持原数据库、项目/运行身份和返回内容,读库等待不占原生窗口线程。运行标记包含真实恢复派发,不能由持久in_progress推断。
验证:TypeScript、Vite构建、聊天增量/渲染/工具摘要回归通过;新增长历史索引、历史可见性切换及工具展开保留、共享高亮跨块不串内容检查通过。运行标记Rust3项、团队恢复9项通过,调试版 `cargo rustc --bin ygent -- -C extra-filename=-chat-read` 编译通过;没有重复旧全量LSP测试来替代员工当前整改验收。
真实1335×916、DPR1下,前一阶段首次打开长任务524ms;按需挂载后同路径长任务60ms、DOM节点约4,848→1,016。滚动历史后重入的锚点偏差0.125px,回到底部间距0;原生复测中没有异常。该原生脚本选中的历史段未包含可展开工具,工具手动展开保留由组件回归证明,不能据空结果宣称原生工具验收通过。最初1.5–1.7秒采样发生在144×19的最小化视口,与正常窗口数据分别保留,不直接作同尺寸提速比例。
前端更新已在现有开发窗口生效。Rust修复已编译,当前PID1964仍为旧调试内核,未重启/替换、未部署安装目录;异步IPC和运行标记需切换新构建后原生复验。用户当前工作及主动取消不因性能修复重新派发。CPU profile、原生DOM/时间和检查日志只保存于私有 `~/.ygent/imports/employee-chat-*`,不提交会话内容。