## 中文
### 背景
L3-external 过去只用 curl 判断 9222,无法区分浏览器未安装、端口未开启、错误产品或伪 CDP
服务,也可能静默回落内置浏览器。
### 变更
- web-access 升级到 3.4.0,并要求先调用 BrowserExternalProbe
- 结构化处理未安装、端口关闭、多候选、产品不匹配、无效 CDP 与宿主不可用
- 显式浏览器不可自动替换;泛指 external 在多候选且无 ready 端口时先询问
- 所有 Playwright 配方使用 probe 返回端口和 DesireCore 隔离 Profile
- 纳入并修复 #93 的浏览器收尾规则与重复编号 finding
### 验证
- validate-i18n:通过
- translate --check:通过
- validate-i18n --online:通过
- source hash:sha256:1704b973e3a90e89
- 双语结构:31 个标题、20 个代码围栏
取代 #93;关联 desirecore/desirecore#2369。
## English
### Background
L3-external previously relied on curl against port 9222, which could not
distinguish a missing browser, a closed debug port, a different product,
or a fake CDP service, and could silently fall back to the built-in
browser.
### Changes
- Bump web-access to 3.4.0 and require BrowserExternalProbe before CDP
attach
- Handle missing installation, closed port, multiple candidates, product
mismatch, invalid CDP, and unavailable host as separate states
- Never replace an explicitly requested browser; ask when a generic
external request has multiple candidates and no ready endpoint
- Use the probe result port and a DesireCore-isolated profile in all
Playwright recipes
- Incorporate #93 browser wrap-up guidance and fix its duplicate
numbering review finding
### Validation
- i18n validation passed
- translation freshness check passed
- online validation passed
- source hash: sha256:1704b973e3a90e89
- bilingual structure: 31 headings and 20 code fences
Supersedes #93; related to desirecore/desirecore#2369.
---------
Co-authored-by: xieyuanxiang <124608760@qq.com>
## 背景 / Background
v3.0(#85)以「它存在的每一条技术理由(无批量取文通道、evaluate 不可用、截图必须串行
activate)都已被内置浏览器覆盖」为由,删除了 Python Playwright 那一层。
**作为「内置浏览器不够用时的兜底」,这个判断是对的。**
但删除时顺带丢掉了一个完全不同的用例:用户想用**他自己那个**浏览器——他的登录态在他自己的 Chrome
里,他想亲眼看着操作、随时接管。这跟能力够不够无关,内置浏览器替代不了。
真实案例:用户要求「请你操作我本地机器的外部浏览器来完成一个示例报关过程」。技能里已无此路径,模型自己也查出「无独立的 Browser*
外部浏览器工具」,仍用内置浏览器做完全程,并以「本地受管浏览器」「已启动本地浏览器」描述——用户拿到的和要的不是一回事,却无从分辨。
v3.0 (#85) removed the Python Playwright layer on the grounds that every
technical reason it existed for is now covered by the built-in browser.
**As a fallback, that judgement was right.** But the deletion also took
a different use case with it: the user wanting *their own* browser —
their login state, their window, theirs to watch and take over. That has
nothing to do with capability, and the built-in browser cannot stand in
for it.
## 改动 / Changes
把 L3-external 作为**由用户意图触发的平级选择**恢复(**不再是 fallback**):
- 恢复 `references/cdp-browser.md`(v3.0 删除,含 `connect_over_cdp` 模板与站点配方)
- 恢复 `Prerequisites: Chrome CDP Setup`,重新定位为「**仅 L3-external
需要**」,内置浏览器仍零前置条件
- 决策树的实时交互分支改为双路:用户点名外部 → L3-external;其余 → 内置(默认)
- 新增「两个浏览器,按用户意图选」对照表:是什么 / 登录态 / 用户能否看到 / 前置条件 / 是否默认
- 分层表加回 L3-external,并说明它**刻意不在默认排序里**——判据是用户点名,不是能力够不够
- 明确:CDP attach 时严禁 `browser.close()`(会关掉用户自己的 Chrome)
- 无论走哪条,措辞必须让用户能分辨实际用了哪个;禁止「本地浏览器」这类两边都像的说法
version 3.0.1 → 3.2.0
## 校验 / Validation
- `python3 scripts/i18n/validate-i18n.py` → OK: no i18n issues found
- `python3 scripts/i18n/translate.py --check` → web-access en-US
`human-locked, skipping`(无 source_hash 漂移)
- 双语同步;en-US 为 human-locked 翻译,已手工同步并按 `compute_source_hash` 重算对齐
## 公开信息边界 / Public information boundary
改动仅涉及浏览器能力边界的技术描述,无租户、客户或其他机密身份信息。
---------
Co-authored-by: Yige <a@wyr.me>