2026-07-25 18:07:57 +08:00
---
id : T-307
title : 受管浏览器意外退出监控与状态提示
phase : 3
deps : [ T-101, T-305, T-306]
2026-07-25 18:23:33 +08:00
status : DONE
2026-07-25 18:07:57 +08:00
created : 2026-07-25
owner : codex
---
## 需求与背景
当前刷新操作可以检查已保存实例的状态,但 Chub 已启动的浏览器被用户手动关闭、崩溃或被外部结束后,GUI 不会立即反馈。用户需要知道对应 Chrome/Edge 已退出,并能安全地重新启动它;这一能力不得变成扫描或接管外部浏览器的通道。
## 方案与边界
- 仅在当前 Chub 应用会话中,为成功启动并注册的 Chrome/Edge 根进程建立一个后台 `Wait` 监控;每个实例最多一个监控 goroutine。外部已关联、外部占用、未知占用和应用启动前已存在的进程均不监控、不提示。
- 退出结果必须携带稳定实例 ID、启动代次、受管 PID、退出码和 `expectedStop` 标记。UI 只接受仍与当前运行时记录完全匹配的结果,忽略删除、重启或再次启动后的迟到结果。
- 监控到意外退出时,先将实例运行时状态改为“已退出”并清空 PID、端口和归属,再排队显示信息提示。提示使用事实性文案“检测到‘实例名’的 Chrome/Edge 已退出”,不声称能区分手动关闭、崩溃或任务管理器结束;说明配置与 User Data Dir 未被删除。
- 提示只有“知道了”操作,Enter/Escape 都可关闭;关闭后焦点返回对应实例的启动按钮。多个实例同时退出时合并显示,已有编辑、未保存确认或删除确认弹层时延后显示,不能叠加或夺走用户输入。
- Chub 请求的优雅停止属于预期退出:停止结果与退出监控只产生一次最终状态,不显示意外退出提示。应用关闭时取消 UI 订阅/提示发布,但不能杀死浏览器;`Wait` 取消也不能隐式关闭进程。
- 运行时 PID、端口、退出码、启动代次和提示队列都不写入实例配置;日志和事件不含代理认证或浏览器私密数据。
## 验收要点
- 成功启动的受管 Chrome/Edge 进程意外结束后,不经 F5 就在合理时间内将对应实例改为“已退出”,启动操作恢复可用;外部状态与其他实例不变。
- 退出提示含实例名称、浏览器类型和“配置、User Data Dir 未删除”的恢复说明;关闭、Escape、Enter 后焦点回到该实例启动按钮。多个退出合并为一个提示。
- 主动停止不弹意外退出提示;停止失败、启动失败、外部关联、PID/代次不匹配、已删除实例、重启前一代退出和窗口关闭后的迟到事件均不改变新状态或弹窗。
- 监控、CDP/进程等待和结果发送均在后台;UI Frame 仅消费通道结果。没有按进程名枚举、终止或接管 Chrome/Edge 的逻辑。
- 覆盖受管退出、预期停止、重复/过期退出、启动后快速退出、多个退出、提示关闭/焦点恢复和应用关闭取消;`gofmt` 、`go test ./...` 、`go vet ./...` 、`go build -o build/chub.exe ./cmd/chub` 、`scripts/smoke-browser.ps1` 与 `scripts/smoke-windows.ps1` 通过。
## 执行记录
2026-07-25 18:23:33 +08:00
- 状态:DONE
- 变更:新增当前会话受管进程的单实例 `Wait` 监控;退出事件按实例 ID、启动代次与 PID 回到 Shell 的线程安全结果队列。意外退出会立即恢复“已退出/启动”状态并合并显示“知道了”提示;Chub 请求停止、外部实例和过期事件不会提示。提示关闭后焦点回到该实例的启动操作。
- 验证:新增命令入口监控与预期停止测试、Shell 的意外退出/启动期快速退出/过期事件/多个退出聚合测试;`go test -race ./cmd/chub ./internal/ui` 、`go test ./...` 、`go vet ./...` 、`scripts/smoke-windows.ps1` 与 `scripts/smoke-browser.ps1` 均通过。
2026-07-25 18:07:57 +08:00
- 阻塞:无。