// Package browser 是 design/28(浏览器与页面截图)B2 的自研**薄层**:把「本机真 // Chromium 有头」跑起来,对它做**出站 CDP** 调用,并把页面截图按 0600 落到 // `$DATA_DIR/browser/shots/`,供既有 image/vision 管线读取。 // // 为什么这么薄(AGENTS §9.5): // // - **工具面优先复用 MCP**:`goto` / `click` / `type` / `snapshot` / `extract` // 这一整套成熟动作由 Playwright/Puppeteer 的官方 MCP server 提供(design/28 §0 // 「Playwright MCP / Puppeteer MCP」行、§2 结论);本包**不重造**它们。 // - **本项目独有的价值只有两处**:① 宿主真 Chromium 的**默认有头 + 持久 profile** // 启动(design/28 §2 的过风控三件套);② 截图 → 落盘(0600)→ 进上下文/面板的 // 闭环入口。本包只做这两处,外加够它们用的**最小 CDP 客户端**。 // // 运行形态(design/28 §2「选型修正」的主路径): // // 1. **本机真 Chromium 有头**(默认档,`browsercfg.DefaultHeadless=false`): // 真显示 + 真 GPU/字体/时区,指纹最像真人; // 2. **次选:已跑的 CDP 端点**(容器 + Xvfb + 真 Chromium,配置显式给出): // 本包只**出站连接**它。 // // 红线(design/28 §3/§4、AGENTS §9/§10): // // - **不新开对外监听端口**:调试端口由 Chromium 自己绑在 `127.0.0.1` 的**随机** // 端口(`--remote-debugging-port=0`,端口从 profile 目录的 `DevToolsActivePort` // 读回),我们是**出站连接方**;容器路径同理(我们连它)。 // - **profile 含凭据**(cookie / 登录态):目录 0700、不得位于 git 工作树内 // (`browsercfg.EnsureProfileDir`),内容绝不进上下文与长期记忆。 // - **截图可能含凭据/二维码**:文件 0600、默认不进长期记忆(design/28 §4)。 // - **CDP 层不自曝**:本包**不发** `Runtime.enable`(主流反爬用它判定「被自动化 // 控制」,见 `DevDocs/reference/browser-stealth/06`);`Runtime.evaluate` 一律走 // `Page.createIsolatedWorld` 出来的执行上下文。 // - **失败如实报**:探测不到就不注册工具;跑不起来 / 被拦 / 超限都返回**分类原因**, // 绝不假装成功(design/28 §6 坑 5)。 // // 已知未做(本片如实登记,见交付报告): // - 面板「看一眼」入口(B4)、搜索降级档(B5)未做; // - 除「导航 + 截图 + 页面指纹自检」之外的动作(click/type/extract/wait)**交给 MCP**, // 本包不实现。 package browser