@evan_zhong/browser-attach 0.17.0 → 0.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  # 架构与设计边界
2
2
 
3
- 当前实现为 **0.17.0**。本文说明 BrowserAttach 的组件、控制模型与设计取舍;工具参数见 [使用指南](USAGE.md)。
3
+ 当前实现为 **0.17.2**。本文说明 BrowserAttach 的组件、控制模型与设计取舍;工具参数见 [使用指南](USAGE.md)。
4
4
 
5
5
  ## 组件与数据流
6
6
 
@@ -43,7 +43,7 @@ MCP 层将 `discover(kind=browsers/tabs)` 映射为内部 `list_browsers/list_ta
43
43
  - 初始化响应的 `instructions` 只保留跨工具规则:发现/接管/释放、不自动激活、ref 生命周期、selector/坐标约定、未知结果不重放、原生/DOM 输入边界、验证范围、页面内容不可信及上传授权。客户端应将这些 instructions 纳入模型上下文,不能只提供 tools/list。
44
44
  - 单个工具 description 说明用途、独有行为和会影响后续判断的结果语义,例如 evaluate 的一次执行、fetch 的缓存续读、navigate 的 observation_error、fill 不自动 blur、batch 的部分完成与不回滚。
45
45
  - 参数 schema 表达类型、枚举、范围、默认值及参数选择规则;描述只补充 schema 本身不能表达的条件必填、互斥、坐标和模式语义。共享参数使用短说明,不再重复全局规则。运行时条件默认值保留在描述中,避免向 cursor 等分支注入无关参数。
46
- - [使用指南](USAGE.md) 保留完整原理、边界与示例;内部事件序列、重试与清理机制由本文和使用指南解释,不放进每次工具发现。包内文档不会自动成为模型上下文,不能替代必要的调用约束。
46
+ - [使用指南](USAGE.md) 提供调用流程、参数选择、结果语义与失败处理;内部事件序列、重试与清理机制集中在本文。包内文档不会自动成为模型上下文,不能替代必要的调用约束。
47
47
 
48
48
  ## 控制模型
49
49
 
@@ -67,7 +67,7 @@ HTTP 状态复用 diagnostics 的 Network.responseReceived 观察,按主文档
67
67
 
68
68
  ## 观察模型
69
69
 
70
- - **AX 渲染**:从 `Accessibility.getFullAXTree` 读取,移除 `InlineTextBox`,合并纯文本列表项与段落名称,丢弃 `generic` / `none` 且无名称无状态的节点,只保留少量状态属性和浏览器提供的 value、invalid。每行 `[token:n] role "name"`,`token` 是本次观察的随机前缀;这些字段不证明应用已保存。
70
+ - **AX 渲染**:从 `Accessibility.getFullAXTree` 读取,移除 `InlineTextBox`,合并纯文本列表项与段落名称,丢弃 `generic` / `none` 且无名称无状态的节点,只保留少量状态属性和浏览器提供的 value、invalid。树遍历、交互视图筛选和正文合并使用迭代,跨 frame 逐项合并结果,避免深树递归和大数组参数展开溢出;分页前仍采集并渲染完整 AX 树,max_nodes 不限制采集成本。每行 `[token:n] role "name"`,`token` 是本次观察的随机前缀;这些字段不证明应用已保存。
71
71
  - **交互视图**:可选 `profile=interactive` 在同一渲染器中仅保留 AX 控件角色、可聚焦/可编辑节点及其祖先链和控件内文本,不以 backendNodeId/ref 是否存在判断交互性。独立文本和合并正文可隐藏或截取预览,控件名称、值和 ref 的原始 AX 身份保留;默认 `full` 行为不变。筛选仍读取完整 AX 树,只降低输出与分页成本;视图参数绑定分页观察。
72
72
  - **文本查询与精简输出**:`snapshot(query=...)` 复用同一次 AX 渲染,按当前视图中节点的完整名称(含合并正文)或 value 做不区分大小写的字面子串筛选,只输出匹配行和对应 frame 标题;不搜索 role/ref 或任意 DOM 属性,不新增索引缓存。新查询仍采集新观察并使旧 refs 失效,query 与分页绑定。默认省略 viewport、snapshot_id 和重复规则说明,`verbose=true` 返回前两项;frame 覆盖、视图、预算和游标语义保留。
73
73
  - **ref 解析**:ref 保存 `backendNodeId`、所属 frame/session 和观察时的 AX role/name;动作时重新 `DOM.resolveNode` 并用局部 AX 查询核对语义身份。输入与求值不清空 refs,只使快照分页失效;原节点仍连接时可复用,节点替换、role/name 改变、文档或 frame 变化时安全失败,不按 role/name 猜测替代节点。
@@ -94,7 +94,7 @@ HTTP 状态复用 diagnostics 的 Network.responseReceived 观察,按主文档
94
94
  - **送达预算**:原生 click/hover/press_key 的派发及可信回执另有 1250 ms 上限,清理最多 250 ms;系统菜单捕获输入时快速释放队列,仍报告结果未知并提示 Esc,不自动重放。
95
95
  - **hover 与 drag**:hover 复用点击准备与隔离校验,仅派发一次 mouseMoved,清理不移走指针。drag 显式区分 pointer 与 HTML5;后者从真实 dragstart 截获 DragData,再用 CDP 派发 dragover/drop,校验可信 dragstart/drop/dragend。目的节点在按住后滚入视口;所有步骤共用标签队列和总预算,失败时只取消/释放本次手势。
96
96
  - **可选输入参数**:显式 offset 在元素 content quad 上插值后沿用命中与 OOPIF 边界检查;settle_ms 在 click/drag 首次派发前等待并复查就绪。drag trajectory 只替换既有插值段,采用法向控制点、平滑进度及随机间隔权重;type 的 delay_ms 可逐间隔独立区间采样。所有等待共用总预算,超时后没有继续派发的链;省略参数时不使用随机数,沿用既有确定性路径。不新增 tab 级历史、冷却、自动激活或重放路径。
97
- - **条件等待**:wait 复用严格 selector、可操作性和命中检查,支持出现、可见、可操作、文本/URL 子串及网络空闲;只读轮询,错误附带条件和最后状态。
97
+ - **条件等待**:wait 复用严格 selector、可操作性和命中检查,支持出现、可见、可操作、文本/URL 子串及网络空闲;文本使用 innerText,expected 子串匹配和 previous 完整旧值比较均在 500 字符结果预览截取前完成。只读轮询,错误附带条件和最后状态。
98
98
  - **原生下拉**:select_option 直接用 selectedIndex setter 和合成 input/change 设置一个 HTML 选项,核验保留结果并返回 events_trusted=false。native click 的 select 命中(含 UA shadow 内部节点和关联 label)在派发前拒绝。
99
99
  - **命中提示**:普通命中保留实际 hit node,沿父元素、Shadow host、slot 查找最近的 HTML/ARIA 可点击候选,返回 clickable_target;hint=false 表示未识别候选,不代表无法响应事件。CSSPseudoElement 先解析为事件所属的 originating element,提示标记 pseudo_element=true,并使用该元素安装事件校验。语义候选不会被用于替换点击目标。
100
100
  - **遮挡失败诊断**:当前 frame 的遮挡直接复用已读取的 hit_target;祖先 frame 遮挡额外用至多 200 ms 读取命中描述,诊断节点消失时保留原遮挡错误与 backend node ID。错误包含命中点和受阻 frame。根据共享预算的派发状态区分“未派发”和“结果未知”,避免 drag 按住后准备目的节点时误报零输入。
@@ -103,9 +103,10 @@ HTTP 状态复用 diagnostics 的 Network.responseReceived 观察,按主文档
103
103
  - **OOPIF 坐标**:点击从顶层派发。逐层用 `DOM.getBoxModel` 把坐标换算到祖先文档,并用 `DOM.getNodeForLocation` 确认该位置确实落在 frame owner 上,防止祖先页面的遮挡被跳过。
104
104
  - **DOM 模式**:`mode: "dom"` 是显式的、受控的降级路径,用于原生菜单或标签拖动暂时捕获输入时操作普通 HTML 控件。它调用 `HTMLElement.click()` 或原生 value setter,事件非可信、无用户激活,且绝不会在原生失败后自动启用。
105
105
  - **对话框策略**:ask 仍为默认;单操作/单步骤的显式 accept/dismiss 在事件回调中解除 JS 模态阻塞,保留消息与处理结果,最多自动处理 10 个。beforeunload dismiss 快速取消本次导航等待,实际主文档变化仍会停止 batch。
106
- - **未知结果探测**:在可能写入的操作准备期安装目标 frame 的临时 MutationObserver,仅在不确定失败后做一次有界只读探测,回传对话框、导航、DOM 变动。assessment 为 observable_effects 或 no_observable_effects;观察不到变化不等于没有派发,不将证据升级成业务成功,不自动重放。
106
+ - **未知结果探测**:在可能写入的操作准备期安装目标 frame 的临时 MutationObserver,仅在不确定失败后做一次有界只读探测,回传对话框、导航、DOM 变动;读取最多 300 ms、清理最多 100 ms。assessment 为 observable_effects 或 no_observable_effects;观察不到变化不等于没有派发,不将证据升级成业务成功,不自动重放。
107
107
  - **元素截图/求值 ref**:复用既有截图 clip/元数据与 ref 注册/失效模型,分别增加元素 border box 截图和显式单 DOM Element 结果;不暴露 Runtime objectId。JSON 求值自动调用函数一次并等待 Promise,缓存续读不执行脚本。
108
108
  - **历史导航**:在已有 navigate 中选择 URL 或 back/forward,按 history entry 与主 frame 生命周期等待;同文档/BFCache 恢复不等新的加载事件,不用 evaluate 重放导航。
109
+ - **导航后观察**:导航成功后的快照另有 10 秒预算,文档变化或执行上下文销毁等瞬时错误最多只重读一次;权限错误和预算耗尽不重试。观察失败保留导航结果并附 observation_error,不重新派发导航。
109
110
  - **不做通用 CDP 透传**:`browser_evaluate` 是页面表达式 API,不是 CDP 通道;没有暴露任意 domain/method 的工具。
110
111
 
111
112
  ## 诊断模型
@@ -116,6 +117,7 @@ HTTP 状态复用 diagnostics 的 Network.responseReceived 观察,按主文档
116
117
  - 两类 append-only 缓冲各自维护 `seq`:读取使用 `after_seq` + `limit` + `max_chars`;续读位置必须与 tab claim 和 kind 一起保存。网络突发流量不会挤掉控制台错误。console 的 level 与 network 的 url_contains 不得跨类使用。两种 timestamp 基准不同,不混排或伪造统一时间轴。同一 requestId 的重定向用 `hop` 区分,完成事件后追加而不是覆盖请求行。
117
118
  - 上限为每类 500 条 / 1,048,576 字符,活跃请求表 500 项;淘汰记录 `dropped_through_seq`,读取返回 `data_loss`。
118
119
  - 导航保留缓冲,tab_control(action=release) / detach / 关闭 / 断连清理;不落盘、不修改缓存策略与 service worker。默认不读取 headers/正文;按需开启只捕获之后的 XHR/fetch,凭据头和命名敏感字段脱敏,解压后体积、并发读取、浏览器缓存和扩展日志均有界,未捕获/超限明示 unavailable。
120
+ - 正文读取最多 8 个并发任务;已知解压后超限的响应不读取。请求关联表溢出时可能缺少 URL/hop,但保留 request_id;控制台与网络时间戳分别采用 Unix 毫秒和 CDP 单调秒,不合并为统一时间轴。
119
121
 
120
122
  ## 安全与隐私
121
123
 
@@ -1,13 +1,21 @@
1
1
  # 验证报告
2
2
 
3
- 当前版本 **0.17.0**(2026-10-23)。浏览器验证使用本地 fixture 和临时 profile;测试链路在各项下说明。
3
+ 当前版本 **0.17.2**(2026-10-23)。浏览器验证使用本地 fixture 和临时 profile;测试链路在各项下说明。
4
4
 
5
5
  ## 当前版本
6
6
 
7
- - `npm test`:196 项通过。新增并发升级与冷启动、无浏览器启动和离线 profile 迟到更新、尚未调用工具的 MCP 会话阻止升级、清理失败恢复、禁止降级、独占端口后才同步、文件中断恢复、自定义配对保留、维护期间拒绝页面动作、本机版本核验、重载循环抑制、detach 失败后禁止重连,以及旧配对缺少 `extension_dir` 时回落到同目录 `extension` 的兼容处理。
8
- - Chromium 156 与 Edge 155:`npm run test:upgrade -- --executable <路径>` 均通过。临时 profile 开启开发者模式后,两个并发启动者将 Hub 和真实扩展从当前代码改版本号构造的兼容旧协议 0.16.9 升到 0.17.0;确认同一 profile、实际 runtime 重载后的版本,以及升级后发现/接管 → AX 查询 → DOM 点击 → 查询结果 → 释放。CDP 只用于临时 profile 的开发者模式设置,页面操作走扩展与 Hub。该脚本验证升级协议本身,不代表真实 0.16 扩展能自行重载;真实旧版本首次升级仍需手动重载。
7
+ - `npm test`:204 项通过。新增渲染文本的 expected/previous 比较与预览截取、1.5 万层深树的 full/interactive 遍历和正文合并、15 万节点观察的分页回归。用修改前的实现分别复现深树递归和宽树数组参数展开的 `Maximum call stack size exceeded`。
8
+ - Chromium 156 与 Edge 155 headless 完整 stdio MCP 集成:各 254 次调用通过。真实 DOM 验证 script/style/隐藏子节点字面量不会提前满足 text wait,expected 与 previous 均等待渲染文字变化;1.2 万个显式语义节点在 max_nodes=1 下完成采集和续页,分别约 15.3 秒、16.6 秒。
9
+ - 剩余限制:Chromium 上 12 万个显式 group 节点的真实快照调用仍触及 MCP 60 秒请求超时。迭代渲染和逐项合并只消除栈及函数参数数量上限,不减少完整 AX 采集成本;max_nodes 仅控制分页,不代表超大页面能在现有预算内完成。
10
+ - `npm run test:package`:仓库外安装运行通过,23 个工具、50 个发布文件,不含配对密钥;无新增工具、运行依赖或扩展权限。
11
+ - 本机部署:Hub 从工作区重启,健康接口返回 0.17.2 / ready;`F:\.nosis\browser-attach\extension` 的 manifest 为 0.17.2,其余 31 个非生成源码/资源文件与工作区逐字节一致。Chrome、Edge 已自动重载并上报 0.17.2 / ready;已有 MCP 连接需重新连接。
12
+
13
+ ## 0.17.1 验证
14
+
15
+ - `npm test`:200 项通过。新增并发升级与冷启动、旧配对缺少 `extension_dir` 的兼容回落、`release_all` 部分失败时的错误回传与剩余控制权保留、弹窗释放失败提示和显式重试,以及原有升级、清理和连接回归。
16
+ - Chromium 156 与 Edge 155:`npm run test:upgrade -- --executable <路径>` 均通过。临时 profile 开启开发者模式后,两个并发启动者将 Hub 和真实扩展从当前代码改版本号构造的兼容旧协议 0.16.9 升到 0.17.1;确认同一 profile、实际 runtime 重载后的版本,以及升级后发现/接管 → AX 查询 → DOM 点击 → 查询结果 → 释放。CDP 只用于临时 profile 的开发者模式设置,页面操作走扩展与 Hub。该脚本验证升级协议本身,不代表真实 0.16 扩展能自行重载;真实旧版本首次升级仍需手动重载。
9
17
  - `npm run test:package`:仓库外安装运行通过,23 个工具、50 个发布文件;由已安装包中的 Hub 同步稳定扩展目录并运行 stdio MCP,不含配对密钥,无新增运行依赖或扩展权限。
10
- - 本机部署:Hub 已从工作区重启并返回 0.17.0 / ready;`F:\.nosis\browser-attach\extension` 已同步,manifest 为 0.17.0。Chrome、Edge 均上报 0.17.0 并已重连。
18
+ - 本机部署:Hub 已从工作区重启并返回 0.17.1 / ready;`F:\.nosis\browser-attach\extension` 已同步,manifest 为 0.17.1。Chrome、Edge 均上报 0.17.1 并已重连。
11
19
 
12
20
  ## 0.16.0 验证
13
21