Feat/desktop bg stop and preview obscure - #1190
Open
xiaomakuaiz wants to merge 15 commits into
Open
Conversation
引擎 733df47 落地 subagentControl(subagent/list + subagent/cancel),
spec P3 的 publishEvent 模型中介方案作废,按 §4 预留升级位直通:
- driver:session_call 新增 background_stop {agent_id}——cap 守卫、
engine_id 寻址、应答 {state,stopped} 与引擎错误原样透传。终态刻意
不走应答:仍由 task_notification 权威回填,引擎更替走既有孤儿对账,
不新增终态路径;Caps 投影新增 subagent_control
- UI:BackgroundBar 任务行常驻「停止」,二段确认(原位变「确认停止?」,
4s 自动回弹)→「停止中…」直至通知收卡;失败回弹并条内外显原因可重试;
engine_caps 无能力或卡缺 agentId(旧 journal)不出入口
- reduce:stopped 通知按「已停止」收卡(chat.tool.bgStopped)——用户
刚点过停止,不再与「执行失败」混词
- 测试:driver 4 条(cap 拒绝/agent_id 校验/RPC 形状/错误透传)、
UI 二段确认/停止中/门控/回弹、reduce stopped 收卡;spec P3 与
ARCHITECTURE 已补齐清单同步
设计预览是 Tauri 原生子 webview,永远画在所有 DOM 之上(z-index 无效), pane 头 ⋯ 菜单落进预览矩形即被截断(2026-08-30 用户报障截图)。 - 新增引用计数的 nativeObscure 信号:浮层 acquire/release,workbench 经 ChatView 的 obscured 订阅读数——previewShow/Hide 的执行权收敛回 workbench 一处。此前设置/待办详情在 App 直呼 show/hide,关闭时的 无条件 previewShow 会把 workbench 因别的浮层(子会话回放等)藏起的 预览重新顶回最上层,典型多写者竞态,一并消灭 - 接入面:命令式菜单(openMenu 全部调用方)、DetailModal 族(工具详情/ 子会话回放/快捷键表/后台结果卡)、待办详情模态、设置模态 - App 启动经共享生命周期队列清一次孤儿原生预览:UI 重载(HMR/webview 崩溃恢复)后上一 DOM 纪元的 webview 无人认领,会永远浮在最上层 - App.test「切换主区页面时强制销毁原生预览」按旧架构(设置=切页卸载 工作台)断言,自设置改模态起在基线上稳定红;按现架构重写为 「启动清扫」+「设置经遮挡信号避让」两条,连同菜单/模态/计数语义补测
eef60f2 删除旧工程 desktop/ui 后,ts-rs export_to 仍指 ../ui/src/gen: 每次 cargo test 都把已退役目录复活成未跟踪噪音;genSync.test 读该目录, 在未跑过 cargo test 的干净检出上必红。 - frame.rs/mod.rs 的 export_to 改指 ../ui-next/src/gen/(生成物除随 rustdoc 更新的头注外逐字节不变,重新生成已入库) - genSync.test.ts 按其自述(「P9 切换后本测试删除」)退役 - frame.rs 头注与 ARCHITECTURE 契约 1/5 的生成路径描述同步
两条报障同区域: - 「点击下拉框预览直接消失」:原生子 webview 永远压在 DOM 之上,浮层 打开时预览必须让位,但让位不等于消失——现在遮挡瞬间先截一帧冻结在 原位再隐藏(选元素弹窗 pickedPreview 的同一手法,限时 800ms,截不到 退文字兜底),浮层浮在冻结帧上,关闭后 previewShow 落地才撤帧,无缝 切回活视图 - 「移动 panel 预览留在原地」:拖格换位/任务列收起是纯位移,不改宿主 尺寸,ResizeObserver 不响,原生 webview 停在旧矩形。改为 rAF 逐帧比对 宿主 getBoundingClientRect,变了才发 preview_set_bounds(静止帧零 IPC), 原 tab/preset 维度的 RO 随之退役(创建路径的 RO 不动) 测试:冻结帧先截后藏/恢复撤帧、截帧失败文字兜底、纯位移补发矩形
Windows 报障:AI 起 python serve html 后整个 desktop 卡死、会话取消 无效。实测定位(用户抓到现场):preview_create 挂起后,后续所有 IPC 跟着挂——preview_* 此前全是同步命令,内联跑在 webview IPC 回调 (主线程)里,一个挂死就把整条 IPC 派发路径连同取消一起带走。 Windows 的挂死土壤:wry 建 WebView2 走 webview2_com::wait_with_pump (嵌套消息泵),期间重入派发的 preview IPC 可以对半建的 webview 做 close/再建,互相绞死泵循环;僵尸 localhost(引擎侧管道缺陷所致,另行 修引擎)放大了创建/报错/churn 密度。macOS 无嵌套泵,故仅 Windows 冻。 - preview_* 全族转 async:IPC 回调即刻返回,挂死只发生在 runtime 工作 线程的任务上,UI/取消/引擎通道照常 - 新增 PREVIEW_LANE(tokio Mutex)串行全族:恢复原先主线程内联给到的 次序保证,并从根上杜绝 WebView2 创建期的重入生命周期操作 - 截图落剪贴板挪出主线程回调(Windows OpenClipboard 是全局锁,可被 他程占住而阻塞主线程消息泵)
WebView2 导航不了原生自定义 scheme:tauri 自定义协议在 Windows 只经
http://{scheme}.localhost 桥接可达(wry 按此形态注册 WebResourceRequested
过滤器),而 tauri 对 WebviewUrl::CustomProtocol 的入口 URL 原样透传不做
平台转换。create_preview 传的 monkeycode-artifact://localhost/… 在
Windows 上导航即失败,本地 HTML 预览从未在 Windows 生效(2026-08-31
报障);讽刺的是导航白名单 is_artifact_url 早就两种形态都认
(ARTIFACT_HTTP_HOST 就是为 Windows 备的),唯独入口没转。macOS 的
WKWebView 支持真自定义协议,故 Mac 一直正常。
- 入口按平台选形态:Windows 走 http://monkeycode-artifact.localhost/…
(路径保持已编码形态,不二次编码);macOS/Linux 维持真自定义协议。
协议处理器只看 path,host 无关,两种形态同一实现
- 地址栏顺带接受 workdir 内的绝对路径(Windows 用户习惯粘贴
c:\xxx\yyy.html 全路径):盘符大小写/反斜杠不敏感地折算成 workdir
相对路径再匹配 repo_preview_files 索引,索引外照旧拒绝
报障截图:Linux 上预览不在面板框内,整宽出现在窗口最下方,主 UI 被挤到 上半。根因在上游:tauri-runtime-wry 在 Linux 把 WindowChild 子 webview pack_start 进窗口的垂直 GtkBox(非定位叠放)——两个 box 孩子把窗口对半 分;且 wry 的 set_bounds 仅在 gtk::Fixed 父容器下生效,我们所有摆位调用 全部空转。原生子 webview 在 Linux 没有定位能力,Fixed/Overlay 重构与 Wayland 窗口定位皆不可靠,不在应用侧强修。 - DesignPreviewWorkbench 增加 inlineFallback(isLinuxShell):localhost 与 artifact 目标都改为 DOM 内嵌 iframe——层级/摆位天然正确,浮层遮挡也 无需冻结帧;artifact 走 monkeycode-artifact:// 自定义协议(对进程内 所有 webview 注册,主 webview 的子框架一样可达,artifactInlineUrl 与 壳侧 artifact_entry_url 同形逐段编码) - 代价明确:依赖原生 eval 的截图/注释/标记/编辑/代码页在 Linux 隐藏; 缩放走 WebKit 的 CSS zoom;刷新/换目标经 iframe key 重载 - 壳侧 preview_create/create_artifact 在 Linux 硬拒防回归 - 测试:既有用例统一钉 mac UA(jsdom UA 是 (darwin)/(linux),会被 hostPlatform 误判翻车),新增 Linux 降级两条 + 协议地址编码一条
iframe 归主 webview 的 CSP 管(原生子 webview 时代预览不受它约束,内嵌 后就撞上了):frame-src 此前只有 'self' blob:,指向 localhost 或 monkeycode-artifact:// 的预览 iframe 一律被拦成白屏(2026-08-31 Linux 实测)。frame-src 放行 localhost/127.0.0.1/[::1] 全端口与 monkeycode-artifact: 协议——与预览地址白名单(previewUrl/preview.rs) 同一条边界,不引入新的可框来源;workbench 注释补上这层隐性耦合。 若 Linux 实测 artifact 目标仍白(webkitgtk 自定义协议在子框架的加载 姿态待真机确认),后手是 read_design_template_html 同款 srcdoc 内联, 机器已存在(uploads.rs)。
回放与实时共用同一套帧词汇:历史会话的回放窗口以旧 task-ended 收尾,
turnEnded 照样为真,切会话又复位了 prevTurnEnded——轮末流水线把回放的
旧轮末当成刚发生的:每次打开历史会话都做一次全工作区 git 扫描,还把
回放里的 localhost URL/设计产物当新产出,强行拉开侧栏自动开预览
(原生 create 打向多半已死的服务;Windows 首开历史会话的连环现场之一)。
修法:useSessionFeed 暴露 sawLive——本次打开后经 frames:{id} 通道收到过
**实时**帧才为真(到达即置位:早于窗口的活帧进缓冲、与窗口同批落地,
按应用时机置位会漏掉同批活轮末);回放走 session_open 返回值,天然不
置位。轮末流水线加此活性闸:
- 打开空闲历史会话:零副作用(徽标交 FilesPanel 打开时自行探测)
- 打开运行中会话:落地在 mid-turn,随后的轮末经实时帧到达,照常触发
- 极快活轮次(started/ended 同批 rAF 归约):经实时通道到达,照常触发
——不可用「观察到 running=true」当判据,批内瞬态观察不到
测试:新增「历史会话回放零副作用」回归;既有活轮用例不动全绿
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.