@evan_zhong/browser-attach 0.17.0 → 0.18.0

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.
package/README.md CHANGED
@@ -8,6 +8,8 @@
8
8
  <strong>English</strong> · <a href="README.zh.md">简体中文</a>
9
9
  </p>
10
10
 
11
+ [![M8ven Score](https://m8ven.ai/badge/mcp/evannzhongg-browserattach-kisqie?v=ad2528ebe8a0fa35e3cf933630840bac)](https://m8ven.ai/mcp/evannzhongg-browserattach-kisqie?s=readme)
12
+
11
13
  Drive the Chrome / Edge tabs you already have open and already signed in from an MCP client. BrowserAttach connects to the browser through a locally paired extension, keeps your existing sign-in state, and needs neither a remote debugging port nor a separate automation browser.
12
14
 
13
15
  [npm](https://www.npmjs.com/package/@evan_zhong/browser-attach) · [Usage guide](docs/USAGE.md) · [Architecture](docs/ARCHITECTURE.md) · [Agent integration](docs/AGENT-INTEGRATION.md) · [Test report](docs/TEST-REPORT.md) · [Issues](https://github.com/EvannZhongg/BrowserAttach/issues) · [Contributing](CONTRIBUTING.md)
@@ -15,7 +17,7 @@ Drive the Chrome / Edge tabs you already have open and already signed in from an
15
17
  ## What it does
16
18
 
17
19
  - Discover multiple browser profiles, pick one precisely, claim a tab exclusively, and release it when done.
18
- - Read the accessibility tree, query it by literal name/value, inspect field values and supported editor models; click, replace-fill and type character by character through current snapshot refs or strict CSS/XPath locators.
20
+ - Read the accessibility tree, query names/values/nearby field context, inspect field values and supported editor models; click, fill and type through refs or strict CSS/XPath, HTML label, placeholder and AX role/name locators. Type can also target the currently focused field explicitly.
19
21
  - Native pointer hover, stepped drags and conditional waits; select HTML options without opening a native popup.
20
22
  - Navigate and go back/forward, open or close tabs, handle JavaScript dialogs, upload local files, and capture the whole page or a single element.
21
23
  - Evaluate JavaScript expressions in the main page; read console, page-error and network lifecycle logs captured after claiming; opt in to bounded, redacted request/response details when XHR/fetch needs verification.
package/README.zh.md CHANGED
@@ -15,7 +15,7 @@
15
15
  ## 能做什么
16
16
 
17
17
  - 发现多个浏览器配置,精确选择并独占接管标签页,完成后释放。
18
- - 读取可访问性树,按字面名称或 value 查询并取得可操作引用,检查字段值和支持的编辑器模型,通过当前快照引用或严格 CSS/XPath 定位点击、替换填写和逐字输入。
18
+ - 读取可访问性树,按名称、value 或邻近字段 context 查询并取得可操作引用,检查字段值和编辑器模型;通过 ref 或严格 CSS/XPath、HTML label、placeholder、AX role/name 定位点击和填写,也可显式向当前聚焦字段逐字输入。
19
19
  - 原生指针悬停、分步拖拽、条件等待;无需打开系统弹层即可选择 HTML 下拉选项。
20
20
  - 导航与历史前进/后退、打开或关闭标签页,处理 JavaScript 对话框,上传本机文件并截取整页或单个元素。
21
21
  - 在主页面执行 JavaScript 表达式,读取接管后的控制台、页面异常和网络生命周期日志;需要校验 XHR/fetch 时显式开启有界、脱敏的请求/响应详情。
@@ -1,6 +1,6 @@
1
1
  # 架构与设计边界
2
2
 
3
- 当前实现为 **0.17.0**。本文说明 BrowserAttach 的组件、控制模型与设计取舍;工具参数见 [使用指南](USAGE.md)。
3
+ 当前实现为 **0.18.0**。本文说明 BrowserAttach 的组件、控制模型与设计取舍;工具参数见 [使用指南](USAGE.md)。
4
4
 
5
5
  ## 组件与数据流
6
6
 
@@ -31,7 +31,7 @@ MCP 客户端
31
31
  | `extension/outcomes.js` | 临时 DOM 变动观察器与有界只读探测,不推断业务成功 |
32
32
  | `extension/fetch.js` | 单页读取的参数、隔离世界采集与每 owner 有界缓存分页;临时页生命周期复用 controller 的 attach、导航和标签队列 |
33
33
  | `extension/{snapshot,navigation,evaluate,diagnostics}.js` | 观察、导航、有界求值结果缓存与分页、日志缓冲 |
34
- | `extension/{locator,text}.js` | 严格 CSS/XPath 定位、每次解析的 frame URL/title/iframe 路径、DOM/字段/支持的编辑器模型读取 |
34
+ | `extension/{locator,text}.js` | 严格 CSS/XPath/HTML label/placeholder/AX role-name 定位、每次解析的 frame URL/title/iframe 路径、DOM/字段/支持的编辑器模型读取 |
35
35
  | `extension/visuals.js`、`click-visuals.js` | 无标题红色原生标签组、临时点击反馈 |
36
36
 
37
37
  Hub 按需后台启动(`ensureHub`),多客户端共享;只监听 loopback。
@@ -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,9 +67,10 @@ 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
- - **文本查询与精简输出**:`snapshot(query=...)` 复用同一次 AX 渲染,按当前视图中节点的完整名称(含合并正文)或 value 做不区分大小写的字面子串筛选,只输出匹配行和对应 frame 标题;不搜索 role/ref 或任意 DOM 属性,不新增索引缓存。新查询仍采集新观察并使旧 refs 失效,query 与分页绑定。默认省略 viewport、snapshot_id 和重复规则说明,`verbose=true` 返回前两项;frame 覆盖、视图、预算和游标语义保留。
72
+ - **文本查询与精简输出**:`snapshot(query=...)` 复用同一次 AX 渲染,按当前视图中节点的完整名称(含合并正文)、value 或字段 context 做不区分大小写的字面子串筛选,只输出匹配行和对应 frame 标题;不搜索 role/ref 或任意 DOM 属性,不新增索引缓存。新查询仍采集新观察并使旧 refs 失效,query 与分页绑定。默认省略 viewport、snapshot_id 和重复规则说明,`verbose=true` 返回前两项;frame 覆盖、视图、预算和游标语义保留。
73
+ - **字段上下文**:表单控件可附带 context 并参与 query,保留至多 160 字符的前一兄弟分支 AX 文本;只在四层以内 generic/none/group 祖先、单控件容器中查找,每次容器/文本遍历分别限制 64/32 节点。不将其伪装为 accessible name,不用于 label 定位或 ref 身份验证;interactive/text=false 也保留提示。
73
74
  - **ref 解析**:ref 保存 `backendNodeId`、所属 frame/session 和观察时的 AX role/name;动作时重新 `DOM.resolveNode` 并用局部 AX 查询核对语义身份。输入与求值不清空 refs,只使快照分页失效;原节点仍连接时可复用,节点替换、role/name 改变、文档或 frame 变化时安全失败,不按 role/name 猜测替代节点。
74
75
  - **双预算**:`max_nodes` 限制节点数,`max_chars` 限制每行序列化后的累计字符数;两者独立,任一耗尽都会返回 `next_cursor`。
75
76
  - **续读**:续读沿用同一份 `state`(`entries`、`refs`、`nextOffset`),所以 refs 在分页过程中保持有效。单个节点放不进预算时直接报错要求提高预算,避免静默截断尾部。
@@ -88,24 +89,27 @@ HTTP 状态复用 diagnostics 的 Network.responseReceived 观察,按主文档
88
89
  ```
89
90
 
90
91
  - **type 与 fill**:fill 替换文字,type 保留选区,逐字符复用原生按键与 keydown 回执;字符之间可延迟,不把 insertText 伪装成键盘序列。浏览器处理 keypress/input 及 preventDefault,非 ASCII 不模拟系统 IME。
92
+ - **焦点输入与语义定位**:type 的 focused=true 与 ref/selector 互斥,复用 press_key 的 frame/开放 Shadow DOM 焦点解析,固定最初可编辑元素并逐字检查,不重新聚焦。selector_type 的 label/placeholder 在隔离世界按真实 HTML 关联/属性查询,role/name 每次读取所选 frame 的 AX 树并严格匹配,以 AX 树顺序支持 nth;统一返回原有节点结构,继续复用输入、命中核验及 batch 流程,无组件库适配器。
91
93
  - **只重试准备**:等待阶段可以反复轮询,但一旦派发就不再重试。超时分为"未派发"和"已派发、结果未知"两种错误文本。
92
94
  - **原生指针就绪检查**:准备前和派发前各做一次至多 500 ms 的有界检查;要求活动、未暂停的 tab 与未最小化的窗口。不满足时以 TAB_NOT_READY 明确报告当前指针输入未派发,并提示 tab_control(action=activate) → snapshot → click。click 不主动激活;仅显式 tab_control(action=activate) 在 focus_window=true 时请求窗口聚焦和 Page.bringToFront。
93
95
  - **焦点信号边界**:OS 窗口失焦、遮挡或 document.visibilityState=hidden 不一定阻止 CDP 输入;document.hasFocus() 在 iframe 导航后也可能为 false。这些值作为 page_state 诊断,不独立拒绝点击。实际送达仍由隔离世界的可信事件回执校验;没有回执时不自动重放。
94
96
  - **送达预算**:原生 click/hover/press_key 的派发及可信回执另有 1250 ms 上限,清理最多 250 ms;系统菜单捕获输入时快速释放队列,仍报告结果未知并提示 Esc,不自动重放。
95
97
  - **hover 与 drag**:hover 复用点击准备与隔离校验,仅派发一次 mouseMoved,清理不移走指针。drag 显式区分 pointer 与 HTML5;后者从真实 dragstart 截获 DragData,再用 CDP 派发 dragover/drop,校验可信 dragstart/drop/dragend。目的节点在按住后滚入视口;所有步骤共用标签队列和总预算,失败时只取消/释放本次手势。
96
98
  - **可选输入参数**:显式 offset 在元素 content quad 上插值后沿用命中与 OOPIF 边界检查;settle_ms 在 click/drag 首次派发前等待并复查就绪。drag trajectory 只替换既有插值段,采用法向控制点、平滑进度及随机间隔权重;type 的 delay_ms 可逐间隔独立区间采样。所有等待共用总预算,超时后没有继续派发的链;省略参数时不使用随机数,沿用既有确定性路径。不新增 tab 级历史、冷却、自动激活或重放路径。
97
- - **条件等待**:wait 复用严格 selector、可操作性和命中检查,支持出现、可见、可操作、文本/URL 子串及网络空闲;只读轮询,错误附带条件和最后状态。
99
+ - **条件等待**:wait 复用严格 selector、可操作性和命中检查,支持出现、可见、可操作、文本/URL 子串及网络空闲;文本使用 innerText,expected 子串匹配和 previous 完整旧值比较均在 500 字符结果预览截取前完成。只读轮询,错误附带条件和最后状态。
98
100
  - **原生下拉**:select_option 直接用 selectedIndex setter 和合成 input/change 设置一个 HTML 选项,核验保留结果并返回 events_trusted=false。native click 的 select 命中(含 UA shadow 内部节点和关联 label)在派发前拒绝。
99
101
  - **命中提示**:普通命中保留实际 hit node,沿父元素、Shadow host、slot 查找最近的 HTML/ARIA 可点击候选,返回 clickable_target;hint=false 表示未识别候选,不代表无法响应事件。CSSPseudoElement 先解析为事件所属的 originating element,提示标记 pseudo_element=true,并使用该元素安装事件校验。语义候选不会被用于替换点击目标。
100
102
  - **遮挡失败诊断**:当前 frame 的遮挡直接复用已读取的 hit_target;祖先 frame 遮挡额外用至多 200 ms 读取命中描述,诊断节点消失时保留原遮挡错误与 backend node ID。错误包含命中点和受阻 frame。根据共享预算的派发状态区分“未派发”和“结果未知”,避免 drag 按住后准备目的节点时误报零输入。
101
103
  - **送达不等于业务完成**:`target_verified` / `delivery_verified` / `value_verified` 分别证明可信事件命中、keydown 送达、字段文本写入;点击、按键、fill 和 batch 返回 `application_result: "not_checked"`。fill 不证明 React 状态、选项提交、blur 校验或保存完成。
102
- - **有限多步输入**:batch 在现有标签队列内执行 1–20 步 click/fill/type/press_key/hover/scroll/select_option/wait,共享至多 30 秒预算,每步可另设更短超时;不增加后台任务、循环或脚本引擎;batch 本身只接受每步重新解析的 selector。所有参数先验证,selector 每步重解析,尚未出现的目标只在准备阶段等待;歧义立即报错。首个失败、主文档变化或接管结束后停止,返回此前结果与失败索引;不回滚、不重放、不自动激活或切换输入模式。start_at 显式跳过已完成前缀,返回 failed_step、next_unattempted_step、retry_failed_step_safe;没有后台作业或自动选择续跑点。
104
+ - **有限多步输入**:batch 在现有标签队列内执行 1–20 步 click/fill/type/press_key/hover/scroll/select_option/wait,共享至多 30 秒预算,每步可另设更短超时;不增加后台任务、循环或脚本引擎;元素目标使用每步重新解析的 selector,type 也接受 focused=true。所有参数先验证,selector 每步重解析,尚未出现的目标只在准备阶段等待;歧义立即报错。首个失败、主文档变化或接管结束后停止,返回此前结果与失败索引;不回滚、不重放、不自动激活或切换输入模式。start_at 显式跳过已完成前缀,返回 failed_step、next_unattempted_step、retry_failed_step_safe;没有后台作业或自动选择续跑点。
103
105
  - **OOPIF 坐标**:点击从顶层派发。逐层用 `DOM.getBoxModel` 把坐标换算到祖先文档,并用 `DOM.getNodeForLocation` 确认该位置确实落在 frame owner 上,防止祖先页面的遮挡被跳过。
104
106
  - **DOM 模式**:`mode: "dom"` 是显式的、受控的降级路径,用于原生菜单或标签拖动暂时捕获输入时操作普通 HTML 控件。它调用 `HTMLElement.click()` 或原生 value setter,事件非可信、无用户激活,且绝不会在原生失败后自动启用。
105
107
  - **对话框策略**:ask 仍为默认;单操作/单步骤的显式 accept/dismiss 在事件回调中解除 JS 模态阻塞,保留消息与处理结果,最多自动处理 10 个。beforeunload dismiss 快速取消本次导航等待,实际主文档变化仍会停止 batch。
106
- - **未知结果探测**:在可能写入的操作准备期安装目标 frame 的临时 MutationObserver,仅在不确定失败后做一次有界只读探测,回传对话框、导航、DOM 变动。assessment 为 observable_effects 或 no_observable_effects;观察不到变化不等于没有派发,不将证据升级成业务成功,不自动重放。
108
+ - **未知结果探测**:在可能写入的操作准备期安装目标 frame 的临时 MutationObserver,仅在不确定失败后做一次有界只读探测,回传对话框、导航、DOM 变动;读取最多 300 ms、清理最多 100 ms。assessment 为 observable_effects 或 no_observable_effects;观察不到变化不等于没有派发,不将证据升级成业务成功,不自动重放。
107
109
  - **元素截图/求值 ref**:复用既有截图 clip/元数据与 ref 注册/失效模型,分别增加元素 border box 截图和显式单 DOM Element 结果;不暴露 Runtime objectId。JSON 求值自动调用函数一次并等待 Promise,缓存续读不执行脚本。
110
+ - **求值预算提示**:JSON 仍按顶层完整项分页;已有输出而下一项超出预算时,在同一响应提供 next_item 的 key/index、required_chars 和是否超过最大页预算。提示只读取缓存,不展开或改写嵌套值,也不提供任意脚本的执行进度。
108
111
  - **历史导航**:在已有 navigate 中选择 URL 或 back/forward,按 history entry 与主 frame 生命周期等待;同文档/BFCache 恢复不等新的加载事件,不用 evaluate 重放导航。
112
+ - **导航后观察**:导航成功后的快照另有 10 秒预算,文档变化或执行上下文销毁等瞬时错误最多只重读一次;权限错误和预算耗尽不重试。观察失败保留导航结果并附 observation_error,不重新派发导航。
109
113
  - **不做通用 CDP 透传**:`browser_evaluate` 是页面表达式 API,不是 CDP 通道;没有暴露任意 domain/method 的工具。
110
114
 
111
115
  ## 诊断模型
@@ -116,6 +120,7 @@ HTTP 状态复用 diagnostics 的 Network.responseReceived 观察,按主文档
116
120
  - 两类 append-only 缓冲各自维护 `seq`:读取使用 `after_seq` + `limit` + `max_chars`;续读位置必须与 tab claim 和 kind 一起保存。网络突发流量不会挤掉控制台错误。console 的 level 与 network 的 url_contains 不得跨类使用。两种 timestamp 基准不同,不混排或伪造统一时间轴。同一 requestId 的重定向用 `hop` 区分,完成事件后追加而不是覆盖请求行。
117
121
  - 上限为每类 500 条 / 1,048,576 字符,活跃请求表 500 项;淘汰记录 `dropped_through_seq`,读取返回 `data_loss`。
118
122
  - 导航保留缓冲,tab_control(action=release) / detach / 关闭 / 断连清理;不落盘、不修改缓存策略与 service worker。默认不读取 headers/正文;按需开启只捕获之后的 XHR/fetch,凭据头和命名敏感字段脱敏,解压后体积、并发读取、浏览器缓存和扩展日志均有界,未捕获/超限明示 unavailable。
123
+ - 正文读取最多 8 个并发任务;已知解压后超限的响应不读取。请求关联表溢出时可能缺少 URL/hop,但保留 request_id;控制台与网络时间戳分别采用 Unix 毫秒和 CDP 单调秒,不合并为统一时间轴。
119
124
 
120
125
  ## 安全与隐私
121
126
 
@@ -129,7 +134,7 @@ HTTP 状态复用 diagnostics 的 Network.responseReceived 观察,按主文档
129
134
 
130
135
  | 能力 | 决策 | 原因 |
131
136
  |---|---|---|
132
- | 定位方式 | AX ref + CSS/XPath selector,可显式 nth | ref 保持观察身份,selector 每次重解析;省略 nth 仍严格要求唯一;索引是调用者明确选择,不猜测同名目标 |
137
+ | 定位方式 | AX ref + CSS/XPath/label/placeholder/role-name selector,可显式 nth | ref 保持观察身份,selector 每次重解析;省略 nth 仍严格要求唯一;context 仅作观察辅助,不猜测标签关系 |
133
138
  | 动作重试 | 只重试派发前的准备 | 网页操作可能提交真实数据,重复派发不可接受 |
134
139
  | DOM 模式 | 需要显式 `mode: "dom"` | 非可信事件、无用户激活,不能当作原生输入的透明替代 |
135
140
  | hover / drag | 原生指针工具,复用 click 准备 | 纯悬停和可信拖拽无法由 click 或页面 evaluate 等价表达 |
@@ -1,13 +1,31 @@
1
1
  # 验证报告
2
2
 
3
- 当前版本 **0.17.0**(2026-10-23)。浏览器验证使用本地 fixture 和临时 profile;测试链路在各项下说明。
3
+ 当前版本 **0.18.0**(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`:213 项通过。新增真实 HTML label/placeholder 匹配、AX role/name 唯一性与树顺序、每次重新解析、focused 参数互斥、失焦停止、batch 预校验、快照 context 查询与 ref 身份、嵌套求值预算首屏提示回归。最后的定位错误文案调整另通过 12 项定位/原语定向测试。
8
+ - Chromium 156、Edge 155 headless:输入集成各 21 个场景、扩展集成各 13 个场景通过。覆盖关联标签填写、placeholder 和 AX role 字段读取、坐标聚焦后输入、延迟打开的自定义 option、闭合 Shadow DOM role 点击、开放 Shadow DOM 焦点输入、同进程及跨进程 iframe 的 role/focused 输入、字段切换焦点后停止,以及缓存续读不重放表达式。测试通过扩展和 Hub 操作页面;CDP 仅用于临时 fixture 设置/断言及关闭测试浏览器。
9
+ - `npm run test:package`:包外安装与 stdio MCP 通过,23 个工具、50 个发布文件,不含配对密钥;工具能力扩展,未新增工具、依赖或扩展权限。
10
+ - 本机部署:Hub 已从工作区重启,健康接口返回 0.18.0 / ready;Chrome、Edge 均已自动重载并上报 0.18.0。稳定扩展目录 `F:\.nosis\browser-attach\extension` 的 manifest 为 0.18.0,其余 31 个非生成源码/资源文件 SHA-256 与工作区一致。原有 MCP 客户端需要重新连接以刷新 schema。
11
+ - 当前边界:label 仅使用真实 HTML 关联,不推断兄弟 div;context 是有界观察提示,不改写 AX name。role 每次采集所选 frame 的完整 AX 树。evaluate 仍按完整嵌套项分页,10 秒默认、最多 30 秒,未加入任意脚本检查点或截图布局 token。
12
+ - 额外测试观察:接管后动态插入再移除跨源 iframe 的组合场景中,后续 network_idle 曾以 inflight=1 超时,原因未在本次定位改动中解决;跨进程输入另在接管前已加载 iframe 的 fixture 中验证通过。本次不包含网络跟踪修复。
13
+
14
+ ## 0.17.2 验证
15
+
16
+ - `npm test`:207 项通过。新增滚动最深匹配、隐藏中间节点、多个分支歧义和候选上限回归;10000 个匹配只做 9999 次包含关系检查,每个文字命中候选只读一次几何信息。保留渲染文本的 expected/previous 比较与预览截取、1.5 万层深树的 full/interactive 遍历和正文合并、15 万节点观察的分页回归。用修改前的实现分别复现深树递归和宽树数组参数展开的 `Maximum call stack size exceeded`。
17
+ - 同版本滚动优化:Chromium 156 与 Edge 155 headless 输入集成各 20 个场景通过,包含真实 DOM 的隐藏中间节点、最深匹配 ref、兄弟分支歧义、selector 消歧及原有延迟加载滚动。保留 10000 候选上限、文字与可见性条件;筛选只比较文档顺序中的相邻匹配,不再两两比较,不代表选择器、子树文字和布局读取的总成本也是线性的。
18
+ - Chromium 156 与 Edge 155 headless 完整 stdio MCP 集成:各 254 次调用通过。真实 DOM 验证 script/style/隐藏子节点字面量不会提前满足 text wait,expected 与 previous 均等待渲染文字变化;1.2 万个显式语义节点在 max_nodes=1 下完成采集和续页,分别约 15.3 秒、16.6 秒。
19
+ - 剩余限制:Chromium 上 12 万个显式 group 节点的真实快照调用仍触及 MCP 60 秒请求超时。迭代渲染和逐项合并只消除栈及函数参数数量上限,不减少完整 AX 采集成本;max_nodes 仅控制分页,不代表超大页面能在现有预算内完成。
20
+ - `npm run test:package`:仓库外安装运行通过,23 个工具、50 个发布文件,不含配对密钥;无新增工具、运行依赖或扩展权限。
21
+ - 本机部署:Hub 从工作区重启,健康接口返回 0.17.2 / ready;`F:\.nosis\browser-attach\extension` 的 manifest 为 0.17.2,其余 31 个非生成源码/资源文件与工作区逐字节一致。滚动优化按要求保持版本号,现有自动重载协议只处理版本递增,已打开的浏览器需手动重新加载扩展才能应用本次优化;已有 MCP 连接需重新连接。
22
+
23
+ ## 0.17.1 验证
24
+
25
+ - `npm test`:200 项通过。新增并发升级与冷启动、旧配对缺少 `extension_dir` 的兼容回落、`release_all` 部分失败时的错误回传与剩余控制权保留、弹窗释放失败提示和显式重试,以及原有升级、清理和连接回归。
26
+ - 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
27
  - `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 并已重连。
28
+ - 本机部署:Hub 已从工作区重启并返回 0.17.1 / ready;`F:\.nosis\browser-attach\extension` 已同步,manifest 为 0.17.1。Chrome、Edge 均上报 0.17.1 并已重连。
11
29
 
12
30
  ## 0.16.0 验证
13
31