yunti-browser-runtime 0.2.0 → 0.2.1

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
@@ -13,6 +13,13 @@ Chrome/Edge 浏览器:查看标签页、读取页面、点击输入、截图
13
13
 
14
14
  它的第一目标是:**部署简单、执行高效、和具体 Agent/平台解耦**。
15
15
 
16
+ `0.2.1+` 默认页面操作路径优先走扩展 content script,不会自动 attach Chrome
17
+ debugger:`yunti_observe_page`、fresh uid 的 `yunti_click` / `yunti_hover` /
18
+ `yunti_fill` / `yunti_select` / `yunti_scroll` / `yunti_type_text` /
19
+ `yunti_press_key` 应作为普通页面操作首选。显式 CDP、trace、部分截图 fallback、
20
+ drag/upload/emulation/resize 和 legacy snapshot 兼容路径仍可能触发 Chrome 的调试横幅,
21
+ 只在确实需要低层能力时使用。
22
+
16
23
  ## 当前定位
17
24
 
18
25
  当前版本是本地单用户 MVP:
@@ -45,7 +52,8 @@ npm install -g yunti-browser-runtime
45
52
  yunti-browser-runtime print-config -- --agent codex --human
46
53
  ```
47
54
 
48
- 把输出的 MCP 配置加入 Agent 后,加载浏览器扩展并刷新任意 `http` / `https` 页面即可。
55
+ 把输出的 MCP 配置加入 Agent 后,加载浏览器扩展并打开或保持任意 `http` / `https`
56
+ 页面即可。扩展会自动扫描可访问页面、注入内容脚本并注册到本地 bridge。
49
57
  默认不需要填写 token,不需要打开扩展 popup,也不需要保存设置。
50
58
 
51
59
  需要独立调试 bridge 时,可以手动运行:
@@ -120,11 +128,11 @@ npm run doctor:json
120
128
  6. 引导我打开 Chrome/Edge 的扩展管理页,开启开发者模式,手动加载扩展目录:
121
129
  $(npm root -g)/yunti-browser-runtime/extension
122
130
  7. 告诉我:扩展默认 bridge URL 是 http://127.0.0.1:48887,本地默认不需要 token,不需要打开 popup,也不需要保存设置。
123
- 8. 打开任意 http/https 页面并刷新。
131
+ 8. 打开或保持任意 http/https 页面;扩展会自动尝试注入并注册已有页面。
124
132
  9. 执行:yunti-browser-runtime doctor
125
133
  10. 如果 doctor 正常,再调用 yunti_list_browser_targets 或 yunti_get_tool_usage_hints 验证你能看到浏览器页面。
126
134
 
127
- 注意:Chrome 扩展不能由 npm 静默安装,必须由我手动在浏览器扩展页加载。扩展加载完成后默认立即可用,不要要求我填写 token、打开 popup 或保存设置;除非 doctor 明确提示 bridge 未运行,才让我单独执行 yunti-browser-runtime bridge。
135
+ 注意:Chrome 扩展不能由 npm 静默安装,必须由我手动在浏览器扩展页加载。扩展加载完成后会自动尝试接管已打开的 http/https 页面,不要默认要求我刷新页面、填写 token、打开 popup 或保存设置;只有 doctor/list targets 仍看不到页面,且确认是浏览器限制或页面未加载完成时,才把刷新目标页作为兜底。
128
136
  ```
129
137
 
130
138
  ## 安装浏览器扩展
@@ -142,7 +150,7 @@ $(npm root -g)/yunti-browser-runtime/extension
142
150
  3. 点击“加载已解压的扩展程序”。
143
151
  4. 选择本项目的 `extension/` 目录。
144
152
  5. 打开任意 `http` 或 `https` 页面。
145
- 6. 刷新目标页面即可连接。
153
+ 6. 扩展会自动扫描并注册可访问页面;如果 doctor 仍看不到页面,再刷新目标页作为兜底。
146
154
 
147
155
  扩展默认使用 `http://127.0.0.1:48887`,本地安装不需要 token,不需要打开 popup,
148
156
  也不需要保存设置。扩展 popup 首屏只显示连接状态;自定义 bridge URL、页面匹配或
@@ -217,6 +225,8 @@ cp -R skills/yunti-browser-runtime ~/.codex/skills/
217
225
 
218
226
  - `yunti_click` / `yunti_hover` 需要 `uid`、`selector`,或同时提供 `x` 和 `y`。
219
227
  - `yunti_fill` 必须提供 `value`,并用 `uid` 或 `selector` 定位;不支持只传坐标。
228
+ - 普通页面操作优先使用 `yunti_observe_page` 返回的 fresh uid;`0.2.1+` 的默认
229
+ fresh-uid action 路径不会自动 attach Chrome debugger。
220
230
  - `yunti_close_page` 按 `browserSessionId` 关闭页面;如只有 `tabId` / `targetId`,请用 `yunti_cdp_send_command` + `Target.closeTarget`。
221
231
  - `yunti_cdp_send_command` 必须提供 `method`;`params` 可选,但传入时必须是 object。
222
232
  - `yunti_forget_learning_memory` 需要 memory `id`,或使用 `all=true` 且 `confirmed=true` 删除全部。
@@ -314,10 +324,11 @@ token。
314
324
 
315
325
  ## 发布状态与后续事项
316
326
 
317
- - 当前稳定发布版本:`yunti-browser-runtime@0.1.3`。
318
- - 当前分支正在收口 `0.2.0` npm/unpacked extension 发布候选版本;`0.2.0`
319
- 增强了 `yunti_observe_page`、fresh uid 操作闭环、结构化恢复诊断、DOM/diagnostic
320
- 脱敏和可选本地控制台。
321
- - 发布后验证命令:`npm run release:verify-published`。
327
+ - 当前源码版本:`yunti-browser-runtime@0.2.1`。
328
+ - 当前已发布 npm 稳定版:`yunti-browser-runtime@0.2.0`。
329
+ - `0.2.1` 修复默认 observe-first 页面动作误触发 Chrome debugger 的问题;
330
+ `0.2.0` 增强了 `yunti_observe_page`、fresh uid
331
+ 操作闭环、结构化恢复诊断、DOM/diagnostic 脱敏和可选本地控制台。
332
+ - `0.2.0` 发布后验证已通过:`npm run release:verify-published`。
322
333
  - 浏览器扩展商店版本不阻塞 `0.2.0` npm 发布;如要上架商店,需要沿
323
334
  `docs/EXTENSION_PERMISSION_STRATEGY.md` 另行设计 store-candidate 权限 UX。
@@ -38,6 +38,17 @@ Use this loop for normal page work:
38
38
  - Coordinates/selectors: use them as recovery or debugging paths when fresh
39
39
  uids are unavailable.
40
40
 
41
+ ## Debugger Boundary
42
+
43
+ - In `0.2.1+`, normal observe-first page actions should not automatically
44
+ attach Chrome debugger. Prefer `yunti_observe_page` plus fresh uid
45
+ `yunti_click`, `yunti_hover`, `yunti_fill`, `yunti_select`, `yunti_scroll`,
46
+ `yunti_type_text`, and `yunti_press_key` on anti-debug-sensitive pages.
47
+ - Chrome debugger banners may still appear for explicit low-level or advanced
48
+ tools such as `yunti_cdp_send_command`, raw CDP diagnostics, performance
49
+ tracing, screenshot fallback paths, drag, upload, emulation, resize, or
50
+ legacy snapshot compatibility.
51
+
41
52
  ## Confirmation Boundary
42
53
 
43
54
  Ask the user for explicit confirmation before:
@@ -82,7 +82,7 @@
82
82
  | P6.6.2 | 已完成 | 商店权限与隐私文案草案 |
83
83
  | P6.6.3 | 已完成 | 商店前权限策略决策 |
84
84
  | P6.6.4 | 后置 | Store candidate 权限 UX 设计 |
85
- | P7.1 | 进行中 | 0.2.0 npm/unpacked 发布收口 |
85
+ | P7.1 | 已完成 | 0.2.0 npm/unpacked 发布收口 |
86
86
 
87
87
  当前 0.2.0 推进快照(2026-07-05):
88
88
 
@@ -2691,7 +2691,7 @@ P6.6.4 后置:
2691
2691
 
2692
2692
  ## P7.1 0.2.0 npm/unpacked 发布收口
2693
2693
 
2694
- 状态:进行中
2694
+ 状态:已完成
2695
2695
 
2696
2696
  目标:
2697
2697
 
@@ -2700,32 +2700,31 @@ P6.6.4 后置:
2700
2700
  完成范围:
2701
2701
 
2702
2702
  - package 和 extension 版本同步提升到 `0.2.0`。
2703
- - README / Release / status / execution plan 更新为 0.2.0 release candidate。
2704
- - 执行 `npm run check:metadata`、`npm run release:prepublish`、真实浏览器 E2E 和
2705
- `npm run release:dry-run`。
2706
- - 不在本切片执行 `npm run release:publish`,除非用户明确要求发布。
2703
+ - README / Release / status / execution plan 先更新为 0.2.0 发布候选状态,并在发布后
2704
+ 更新为已发布状态。
2705
+ - 执行 `npm run check:metadata`、`npm run release:prepublish`、真实浏览器 E2E、
2706
+ `npm run release:dry-run`、`npm run release:publish` 和
2707
+ `npm run release:verify-published`。
2707
2708
 
2708
2709
  当前验证:
2709
2710
 
2710
2711
  - `git diff --check` 通过。
2711
2712
  - token 残留检查无输出。
2712
- - `npm run check:metadata` 曾通过,确认 GitHub repository/homepage/bugs URL 为 200
2713
- npm registry 当前已发布版本为 `0.1.3`;随后同一检查因当前环境访问 GitHub 超时而失败。
2714
- - `npm run release:check` 通过,包含 public documentation residue check、17 个公开
2713
+ - `npm run check:metadata` 通过,确认 GitHub repository/homepage/bugs URL 为 200
2714
+ - `npm run release:check` 通过,包含 public documentation residue check、18 个公开
2715
2715
  Markdown 文件链接检查、version consistency check `0.2.0`、CLI smoke `0.2.0`、
2716
- action result coverage 11 行、npm package 内容 48 个文件和 extension zip 内容 13 个文件。
2716
+ action result coverage 11 行、npm package 内容 49 个文件和 extension zip 内容 13 个文件。
2717
2717
  - `YUNTI_E2E=1 npm run test:e2e` 在本机 `pytest-playwright` 环境下通过 1 个真实浏览器
2718
2718
  extension bridge smoke;conda 仅打印 requests 依赖版本 warning,不影响结果。
2719
- - `npm publish --dry-run --registry=https://registry.npmjs.org/` 通过,生成
2720
- `yunti-browser-runtime-0.2.0.tgz` dry-run 预览,tarball 共 48 个文件。
2721
- - `npm run release:prepublish` `npm run release:dry-run` 当前仍受
2722
- `check:metadata` GitHub 请求超时影响,需要网络恢复后重跑。
2719
+ - `npm run release:dry-run` 通过,生成 `yunti-browser-runtime-0.2.0.tgz` dry-run
2720
+ 预览,tarball 共 49 个文件。
2721
+ - `npm run release:publish` 已发布 `yunti-browser-runtime@0.2.0` 到官方 npm registry。
2722
+ - `npm run release:verify-published` 已验证 name、version、repository、homepage、bugs
2723
+ 和 tarball URL。
2723
2724
 
2724
2725
  下一步:
2725
2726
 
2726
- - 网络恢复后重跑 `npm run check:metadata`、`npm run release:prepublish`
2727
- `npm run release:dry-run`。
2728
- - 上述脚本门禁全部通过后,由用户确认是否执行正式 npm publish。
2727
+ - 选择 post-0.2 下一阶段;P6.6.4 store-candidate 权限 UX 仍作为浏览器商店方向后置。
2729
2728
 
2730
2729
  详细范围、非目标和验收标准见 `docs/NEXT_MAJOR_PLAN.md`。
2731
2730
 
@@ -2768,8 +2767,43 @@ rg "/U[s]ers|C[o]deg|x[y]y|y[b]m100" README.md docs skills package.json
2768
2767
 
2769
2768
  ## 当前下一步
2770
2769
 
2771
- P0.1-P6.0 已完成,`yunti-browser-runtime@0.1.3` 已发布到官方 npm registry。
2772
- 当前分支正在收口 `0.2.0` npm/unpacked release candidate。
2770
+ P0.1-P7.1 已完成,`yunti-browser-runtime@0.2.0` 已发布到官方 npm registry。
2771
+
2772
+ ## P7.2 0.2.1 安装后自动注入 / 自动注册页面
2773
+
2774
+ 状态:实施中,代码与文档已完成,等待完整验证和提交。
2775
+
2776
+ 目标:
2777
+
2778
+ 让用户加载扩展后尽量不需要手动刷新页面。扩展后台应主动扫描可访问的 `http` /
2779
+ `https` tabs,对没有注册 session 的页面注入 `dom-observer.js`、`content.js` 和
2780
+ `content.css`,再触发 `yunti_refresh_registration`,使 Agent 能直接发现和操作已打开页面。
2781
+ bridge 重启或 background service worker 恢复后,也应尽量自动恢复注册。
2782
+
2783
+ 非目标:
2784
+
2785
+ - 不绕过 Chrome 对 `chrome://`、扩展页、Web Store、权限不足页面等不可注入页面的限制。
2786
+ - 不引入远程服务、不要求用户填写 token、不要求默认打开 popup。
2787
+ - 不改变普通 observe-first action 的非 CDP 默认路径。
2788
+
2789
+ 验收:
2790
+
2791
+ - manifest 增加必要的 `scripting` 能力。
2792
+ - background/session manager 支持 scan -> ping -> inject -> refresh registration。
2793
+ - 安装/startup、tab update/activation、popup refresh、targets inventory/recovery 等路径能触发恢复。
2794
+ - README / INSTALL / skill / Tool Guide / usage hints / doctor guidance 不再默认要求用户刷新;
2795
+ 只把刷新作为无法注入时的兜底恢复。
2796
+ - `git diff --check`、token 残留检查、`npm run release:check` 通过;涉及真实浏览器链路时执行
2797
+ `YUNTI_E2E=1 npm run test:e2e`。
2798
+
2799
+ 进展:
2800
+
2801
+ - manifest 已新增 `scripting` 权限,用于向已打开的受支持页面注入打包内容脚本。
2802
+ - session manager 已支持 scan -> ping -> inject -> refresh registration,并带同页短时间去重。
2803
+ - background 已接入 install/startup/background start、tab activated、tab updated complete。
2804
+ - popup refresh 和 `yunti_list_browser_targets` 已接入自动恢复。
2805
+ - README、INSTALL、doctor、console guidance、skill、store/permission docs 已改为自动注册优先,
2806
+ 刷新页面只作为浏览器限制下的兜底。
2773
2807
 
2774
2808
  - 发布后验证已通过:`npm run release:verify-published`。
2775
2809
  - 本地默认使用不再需要 bridge token;需要加固时可显式设置
@@ -2783,7 +2817,7 @@ P0.1-P6.0 已完成,`yunti-browser-runtime@0.1.3` 已发布到官方 npm regis
2783
2817
  P6.5.2 控制台诊断增强第一刀已完成,P6.5.3 控制台真实浏览器 E2E 验收已完成,
2784
2818
  P6.6.1 浏览器扩展分发准备已完成,P6.6.2 商店权限与隐私文案草案已完成,
2785
2819
  P6.6.3 商店前权限策略决策已完成。P6.6.4 Store candidate 权限 UX 设计已后置;
2786
- 当前进入 P7.1 0.2.0 npm/unpacked 发布收口。
2820
+ P7.1 0.2.0 npm/unpacked 发布收口已完成。
2787
2821
  - 保持兼容:不改变成功 fill、select、scroll、CDP、截图、network/console、file upload 或 tab
2788
2822
  能力;新增诊断只在失败结果或 observe 元数据里追加更具体的 `code`、`recoveryHint`、
2789
2823
  `element` / 字段状态摘要和验证提示。
@@ -56,6 +56,7 @@ Current file: `extension/manifest.json`.
56
56
  | `manifest_version` | `3` | Required modern extension format. | Low. | Keep. |
57
57
  | `permissions.activeTab` | present | Visible-tab capture fallback and temporary page access semantics. | Low to medium; generally narrower than persistent host access. | Keep. |
58
58
  | `permissions.debugger` | present | CDP commands, target-level automation, console/runtime/network events, and low-level recovery. | High. Chrome shows a debugger warning and reviewers may ask why this is core. | Keep for now; store copy must explain this is the core browser automation transport. |
59
+ | `permissions.scripting` | present | Programmatically inject packaged content scripts into already-open supported pages after extension load or recovery. | Medium with broad host access; reviewers may ask why dynamic injection is needed. | Keep for developer/npm path so install does not require manual page refresh; explain it as recovery/registration, not arbitrary remote code execution. |
59
60
  | `permissions.storage` | present | Local bridge URL, optional token, user id/name, and page match settings. | Low. | Keep. |
60
61
  | `permissions.tabs` | present | Tab inventory, active tab selection, switching, and metadata routing. | Medium. Chrome may warn about browsing history. | Keep for now; evaluate whether any read paths can use host/activeTab data later. |
61
62
  | `permissions.webRequest` | present | Sanitized network diagnostics and request observation. | Medium to high with broad hosts. | Keep for now; P6.6.2 should evaluate optionalizing network diagnostics. |
@@ -12,7 +12,7 @@ current `0.2.0` development cycle:
12
12
  - broad `http` / `https` host access remains acceptable for the local developer
13
13
  and npm-installed extension path;
14
14
  - `webRequest` remains available by default for local diagnostics;
15
- - `debugger`, `tabs`, screenshots, CDP, network, console, upload, and tab
15
+ - `debugger`, `scripting`, `tabs`, screenshots, CDP, network, console, upload, and tab
16
16
  capabilities remain part of Yunti's core local browser automation surface;
17
17
  - the current manifest should not be submitted to Chrome Web Store or Edge
18
18
  Add-ons as the recommended store build without an explicit maintainer
@@ -47,7 +47,7 @@ developer install:
47
47
  - Edge policy says extensions should request only permissions essential for the
48
48
  declared functionality, and must clearly disclose dependency on non-integrated
49
49
  software and testing steps.
50
- - Yunti's current `debugger`, broad host access, `tabs`, and `webRequest`
50
+ - Yunti's current `debugger`, `scripting`, broad host access, `tabs`, and `webRequest`
51
51
  combination is truthful for a browser automation runtime, but it is also the
52
52
  highest-review-burden shape.
53
53
 
@@ -74,9 +74,11 @@ The safest product path is therefore:
74
74
 
75
75
  Keep current behavior:
76
76
 
77
- - `permissions`: `activeTab`, `debugger`, `storage`, `tabs`, `webRequest`.
77
+ - `permissions`: `activeTab`, `debugger`, `scripting`, `storage`, `tabs`, `webRequest`.
78
78
  - `host_permissions`: `http://*/*`, `https://*/*`, localhost bridge access.
79
79
  - Static content scripts for `http` / `https` pages.
80
+ - Programmatic injection for already-open supported pages after extension load,
81
+ startup, bridge recovery, or target inventory refresh.
80
82
  - Popup remains zero-config by default.
81
83
  - Advanced page match patterns remain a runtime registration filter, not a
82
84
  browser permission boundary.
@@ -113,9 +115,10 @@ Before any store build with narrowed permissions:
113
115
  when the current page is blocked by missing host permission.
114
116
  - Agent-facing errors should say whether the page is unavailable because host
115
117
  permission is missing, the bridge is offline, the page is unsupported, or the
116
- extension needs a refresh.
118
+ browser blocked automatic injection.
117
119
  - Tool hints and the packaged skill should explain how to recover:
118
- `open page -> grant site access -> refresh -> yunti_list_browser_targets`.
120
+ `open page -> grant site access -> yunti_list_browser_targets`, with page
121
+ refresh only as a fallback.
119
122
  - Optional network diagnostics should be visibly separate from basic DOM
120
123
  automation.
121
124
  - `doctor` should detect permission-mode problems and provide a human-readable
@@ -136,7 +139,7 @@ small and testable:
136
139
  6. Add real-browser E2E coverage for:
137
140
  - page blocked before host grant;
138
141
  - grant access;
139
- - refresh/register;
142
+ - auto-register existing pages;
140
143
  - observe/action success;
141
144
  - optional diagnostics enabled/disabled.
142
145
  7. Update store copy and privacy text after the final manifest strategy is
@@ -84,6 +84,7 @@ Edge certification notes, and any public privacy-policy explanation.
84
84
  | --- | --- | --- | --- |
85
85
  | `activeTab` | Allows temporary access to the visible tab for user-directed capture and fallback operations. | Used as a narrower visible-tab fallback where possible. It does not replace persistent access needed for the current automation workflow. | Keep. |
86
86
  | `debugger` | Enables the local agent to control the user's browser tab through the browser's debugging protocol. | Core transport for CDP commands, target routing, console/runtime diagnostics, screenshots, and low-level recovery. This is high-sensitivity and must be explained as the product's primary browser automation mechanism. | Keep for current developer path; re-review before store submission. |
87
+ | `scripting` | Lets the extension inject its packaged content scripts into supported pages that were already open before the extension loaded. | Used for automatic page registration and recovery after install, browser startup, or background service worker restart. It does not execute remote code. | Keep for current developer path so users do not need to refresh pages by default; re-review before store submission. |
87
88
  | `storage` | Saves local extension settings such as bridge URL, optional token, user id/name, and page match settings. | Stores local configuration only. It is not used for hosted sync by default. | Keep. |
88
89
  | `tabs` | Lets the agent list and switch the user's open browser tabs. | Needed for tab inventory, target selection, activation, and routing metadata. Store copy should explain that tab metadata is used only for user-directed local automation. | Keep for current workflow; evaluate narrower alternatives later. |
89
90
  | `webRequest` | Lets the runtime provide sanitized network diagnostics when debugging page automation. | Used for observation and diagnostics, not ad blocking or request modification. Because this combines with broad hosts, consider making network diagnostics optional in a later slice. | Keep for developer path; P6.6.3 should decide optionalization. |
@@ -151,7 +152,9 @@ include install and test steps:
151
152
  2. Install the runtime package.
152
153
  3. Start or configure an MCP-capable agent so it launches the local bridge.
153
154
  4. Install the extension build.
154
- 5. Open and refresh an `http` or `https` page.
155
+ 5. Open or keep an `http` or `https` page; the extension auto-registers
156
+ accessible pages and only needs a refresh if browser restrictions prevent
157
+ injection.
155
158
  6. Run `yunti-browser-runtime doctor`.
156
159
  7. Verify that the extension shows a connected page and that MCP tools can list
157
160
  browser targets.
package/docs/INSTALL.md CHANGED
@@ -63,7 +63,8 @@ Development loading:
63
63
  2. Enable developer mode.
64
64
  3. Choose "Load unpacked".
65
65
  4. Select the project `extension/` directory.
66
- 5. Open or refresh any `http` or `https` page.
66
+ 5. Open or keep any `http` or `https` page. The extension automatically tries
67
+ to inject and register accessible existing pages.
67
68
  6. Do not open the extension popup unless you want to confirm status or
68
69
  customize settings.
69
70
 
@@ -150,8 +151,9 @@ npm run print-config -- --agent cline --human
150
151
  ```
151
152
 
152
153
  Add the printed server entry to Cline's MCP settings. Keep the extension loaded
153
- in Chrome/Edge and refresh the target page so the content script registers a
154
- fresh `browserSessionId`.
154
+ in Chrome/Edge. The extension should register accessible `http`/`https` pages
155
+ automatically; refresh the target page only if browser restrictions or a failed
156
+ doctor check make it necessary.
155
157
 
156
158
  ## Check Health
157
159
 
@@ -187,7 +189,9 @@ runs the unit test suite, and verifies the npm package contents with
187
189
 
188
190
  ## Common Recovery
189
191
 
190
- - If tools say no browser tab is connected, refresh the target page.
192
+ - If tools say no browser tab is connected, call `yunti_list_browser_targets`
193
+ or run doctor first; the extension will try to auto-register accessible pages.
194
+ Refresh the target page only as a fallback.
191
195
  - If doctor reports `authorized: false` with `authRequired: true`, set
192
196
  `YUNTI_BROWSER_BRIDGE_TOKEN` and save the same token in the extension popup.
193
197
  - If an old `browserSessionId` fails, call `yunti_list_browser_targets` again
@@ -198,8 +202,9 @@ runs the unit test suite, and verifies the npm package contents with
198
202
  is rejected.
199
203
  - For closing a raw `tabId` or `targetId`, use `yunti_cdp_send_command` with
200
204
  `Target.closeTarget` instead of `yunti_close_page`.
201
- - If the extension was reloaded, refresh browser pages so the content script can
202
- register again.
205
+ - If the extension was reloaded, it should scan and register accessible pages
206
+ automatically. Refresh browser pages only if the page cannot be injected or
207
+ remains invisible after the recovery check.
203
208
 
204
209
  ## Real Browser Smoke Test
205
210
 
@@ -1,7 +1,7 @@
1
1
  # Next Major Plan: 0.2.0 Best Browser Automation Runtime
2
2
 
3
- This document is the durable planning contract for the next major development
4
- cycle after `yunti-browser-runtime@0.1.3`.
3
+ This document is the durable planning contract for the `0.2.0` development
4
+ cycle, now completed by `yunti-browser-runtime@0.2.0`.
5
5
 
6
6
  ## Goal
7
7
 
@@ -708,14 +708,14 @@ P6.6.4 deferred:
708
708
 
709
709
  ### P7.1 0.2.0 Release Closure
710
710
 
711
- Status: in progress.
711
+ Status: completed.
712
712
 
713
713
  Scope:
714
714
 
715
715
  - bump package and extension versions to `0.2.0`;
716
716
  - preserve the npm/unpacked developer path and current local runtime behavior;
717
- - run metadata, release, real-browser E2E, and dry-run gates;
718
- - ask for explicit user confirmation before formal npm publish.
717
+ - run metadata, release, real-browser E2E, dry-run, publish, and
718
+ post-publish verification gates.
719
719
 
720
720
  ## Suggested Implementation Order
721
721
 
@@ -2,17 +2,49 @@
2
2
 
3
3
  ## Current Phase
4
4
 
5
- Patch release `yunti-browser-runtime@0.1.3` is complete. The project is now
6
- closing the `0.2.0 Best Browser Automation Runtime` npm/unpacked release
7
- candidate, documented in `docs/NEXT_MAJOR_PLAN.md`.
5
+ Release `yunti-browser-runtime@0.2.0` is complete and verified on the official
6
+ npm registry. The current patch line is `0.2.1`, focused on making default
7
+ observe-first page actions avoid automatic Chrome debugger attachment.
8
8
 
9
- Current implementation focus: P7.1 `0.2.0` npm/unpacked release closure.
9
+ Current implementation focus: `0.2.1` install/bridge recovery without default
10
+ manual page refresh. The anti-debug-sensitive default action path is already in
11
+ place: fresh-uid `yunti_click`, `yunti_hover`, `yunti_fill`, `yunti_select`,
12
+ `yunti_type_text`, and `yunti_press_key` dispatch through content script page
13
+ events instead of CDP mouse/keyboard/runtime commands. Explicit CDP, trace,
14
+ screenshot fallback, drag/upload/emulation/resize, and legacy snapshot
15
+ compatibility remain low-level/advanced paths that may show the Chrome debugger
16
+ banner.
17
+
18
+ Post-0.2 planning remains active after this patch.
10
19
  P6.6.1 browser extension distribution readiness, P6.6.2 store-facing
11
20
  permission/privacy copy, and P6.6.3 pre-store permission strategy decision are
12
21
  complete; P6.5 optional local runtime console is complete through real-browser
13
22
  validation. P6.6.4 store-candidate permission UX design is deferred to the
14
23
  post-0.2 store-candidate track.
15
24
 
25
+ Active slice status: `0.2.1` install/bridge recovery has code and docs in
26
+ progress. The extension background scans accessible `http` / `https` tabs after
27
+ install/startup/background recovery, tab activation/update, popup refresh, and
28
+ `yunti_list_browser_targets`; it pings existing content scripts, injects the
29
+ packaged scripts when missing, and triggers registration automatically. Manual
30
+ refresh is now documented as a last resort only for pages Chrome cannot inject
31
+ into, unsupported protocols, missing permissions, or other browser-enforced
32
+ limits.
33
+
34
+ Acceptance for this slice:
35
+
36
+ - Add `scripting`-based auto injection / auto registration for existing
37
+ supported tabs.
38
+ - Trigger recovery on extension install/startup, tab activation/update, popup
39
+ refresh, and list-targets style inventory recovery where feasible.
40
+ - Keep the content-script observe/action path non-CDP by default.
41
+ - Update README, install guide, skill, Tool Guide, and usage hints so agents no
42
+ longer tell users to refresh as the default post-install step.
43
+ - Doctor/no-session guidance should prefer automatic recovery and mention manual
44
+ refresh only as a fallback.
45
+ - Verify with unit tests, release checks, and real-browser E2E if browser
46
+ behavior changes.
47
+
16
48
  Latest visible 0.2.0 phase split:
17
49
 
18
50
  - P6.1.1 completed: `yunti_observe_page` schema, tool hints, and bridge
@@ -77,7 +109,7 @@ Latest visible 0.2.0 phase split:
77
109
  - P6.6.2 completed: store-facing permission and privacy copy.
78
110
  - P6.6.3 completed: pre-store permission strategy decision.
79
111
  - P6.6.4 deferred: store-candidate permission UX design.
80
- - P7.1 in progress: `0.2.0` npm/unpacked release closure.
112
+ - P7.1 completed: `0.2.0` npm/unpacked release closure and npm publication.
81
113
 
82
114
  Latest detailed P6.2 status:
83
115
 
@@ -315,18 +347,11 @@ Latest detailed P6.2 status:
315
347
  public documentation residue checks, public Markdown link checks for 17 files,
316
348
  11 action-result coverage rows, npm package contents validation with 48
317
349
  files, and extension zip contents validation with 13 files.
318
- - Next: complete P7.1 `0.2.0` npm/unpacked release closure. Version has moved
319
- to `0.2.0`; run metadata, release, real-browser E2E, and dry-run gates before
320
- asking for confirmation to publish. P6.6.4 store-candidate permission UX is
321
- intentionally deferred and should not block this npm/unpacked release.
322
- - P7.1 current validation: package and extension versions are both `0.2.0`;
323
- `git diff --check`, token residue grep, `npm run release:check`,
324
- `YUNTI_E2E=1 npm run test:e2e`, and direct
325
- `npm publish --dry-run --registry=https://registry.npmjs.org/` passed.
326
- `npm run check:metadata` passed once for the public GitHub/npm metadata, then
327
- later failed because this environment timed out connecting to GitHub; scripted
328
- `release:prepublish` and `release:dry-run` need to be rerun when GitHub is
329
- reachable again.
350
+ - P7.1 completed: package and extension versions are both `0.2.0`; metadata,
351
+ release, dry-run, publish, and post-publish verification gates passed.
352
+ `npm run release:publish` published `yunti-browser-runtime@0.2.0` to the
353
+ official npm registry, and `npm run release:verify-published` verified the
354
+ published package metadata and tarball URL.
330
355
 
331
356
  ## Current State
332
357
 
@@ -364,9 +389,7 @@ Latest detailed P6.2 status:
364
389
  - `npm run release:dry-run` and `npm run release:publish` pin the official npm
365
390
  registry at `https://registry.npmjs.org/`, avoiding accidental publication to
366
391
  a locally configured mirror registry.
367
- - `yunti-browser-runtime@0.1.3` is published on the official npm registry.
368
- - Current branch package and extension versions are being prepared as
369
- `0.2.0` release candidate.
392
+ - `yunti-browser-runtime@0.2.0` is published on the official npm registry.
370
393
  - Extension popup is a zero-config status panel by default; Bridge URL, page
371
394
  matching, and optional Bridge Token stay under advanced settings.
372
395
  - `npm run test:e2e` provides an opt-in real-browser Playwright smoke test for
@@ -1102,8 +1125,9 @@ Latest detailed P6.2 status:
1102
1125
  real-browser console validation. P6.6.1 browser extension distribution
1103
1126
  readiness, P6.6.2 store-facing permission/privacy copy, and P6.6.3 pre-store
1104
1127
  permission strategy decision are complete. P6.6.4 store-candidate permission
1105
- UX design is deferred to post-0.2. The next anchored slice is P7.1 `0.2.0`
1106
- npm/unpacked release closure.
1128
+ UX design is deferred to post-0.2. The next anchored slice should be chosen
1129
+ from post-0.2 planning, with browser-store permission UX still available as a
1130
+ separate store-candidate track.
1107
1131
  - For the next coding slice, update all affected guidance surfaces in one
1108
1132
  commit: `mcp/tools.js`, `docs/TOOL_GUIDE.md`,
1109
1133
  `skills/yunti-browser-runtime/SKILL.md`, `docs/EXECUTION_PLAN.md`, and this
@@ -101,7 +101,9 @@ Yunti 继续坚持自己的特色:
101
101
 
102
102
  - popup 首屏是零配置状态面板;
103
103
  - bridge URL、page match、optional token 放入高级设置;
104
- - 默认加载扩展、刷新任意 `http` / `https` 页面即可连接;
104
+ - `0.2.0` 默认加载扩展、刷新任意 `http` / `https` 页面即可连接;
105
+ - `0.2.1` 进一步改进为加载扩展后自动扫描、注入并注册可访问的已打开页面,
106
+ 刷新页面只作为浏览器限制下的兜底;
105
107
  - 不需要打开 popup、不需要保存设置、不需要填 token;
106
108
  - popup 仍可用于高级调试和自定义配置。
107
109
 
@@ -641,7 +643,7 @@ http://127.0.0.1:48887/console
641
643
  - store-candidate manifest;
642
644
  - 商店权限相关测试。
643
645
 
644
- 当前发布目标是 npm/unpacked release candidate,而不是浏览器商店提交版。
646
+ 0.2.0 发布目标是 npm/unpacked release,而不是浏览器商店提交版。
645
647
 
646
648
  ## 发布门禁增强
647
649
 
@@ -775,14 +777,14 @@ http://127.0.0.1:48887/console
775
777
 
776
778
  这些边界是主动选择。当前重点是把 Yunti 做成可靠的本地浏览器操作层。
777
779
 
778
- ## 发布前清单
780
+ ## 发布前后清单
779
781
 
780
782
  正式发布 `0.2.0` 前确认:
781
783
 
782
784
  - 工作区干净;
783
785
  - `package.json` 是 `0.2.0`;
784
786
  - `extension/manifest.json` 是 `0.2.0`;
785
- - README 在发布前仍说明稳定版为 `0.1.3`,发布后再改成 `0.2.0`;
787
+ - README 发布前仍说明稳定版为 `0.1.3`,发布后改成 `0.2.0`;
786
788
  - browser store 工作明确为 post-0.2;
787
789
  - public files 没有 npm/GitHub 凭据或 registry auth 配置片段;
788
790
  - `npm run check:metadata` 通过;
@@ -803,7 +805,12 @@ npm run release:publish
803
805
  npm run release:verify-published
804
806
  ```
805
807
 
806
- 发布后还需要把 README 和状态文档从 release candidate 更新为已经发布的 `0.2.0`。
808
+ 发布结果:
809
+
810
+ - `npm run release:publish` 已发布 `yunti-browser-runtime@0.2.0`;
811
+ - `npm run release:verify-published` 已验证 name、version、repository、homepage、bugs
812
+ 和 tarball URL;
813
+ - README 和状态文档已从发布候选状态更新为已经发布的 `0.2.0`。
807
814
 
808
815
  ## 对外 changelog 短版
809
816
 
@@ -143,6 +143,14 @@ taking an action whose effect cannot be verified from page state.
143
143
 
144
144
  ## CDP Rules
145
145
 
146
+ - In `0.2.1+`, normal observe-first page actions should not automatically
147
+ attach Chrome debugger. Prefer `yunti_observe_page` plus fresh uid
148
+ `yunti_click`, `yunti_hover`, `yunti_fill`, `yunti_select`, `yunti_scroll`,
149
+ `yunti_type_text`, and `yunti_press_key` on anti-debug-sensitive pages.
150
+ - Chrome debugger banners may still appear for explicit low-level or advanced
151
+ tools such as `yunti_cdp_send_command`, raw CDP diagnostics, performance
152
+ tracing, screenshot fallback paths, drag, upload, emulation, resize, or
153
+ legacy snapshot compatibility.
146
154
  - Do not run CDP method names in a shell.
147
155
  - Use `yunti_cdp_send_command` with `method` and optional `params`.
148
156
  - `params` must be an object when provided.
@@ -18,6 +18,7 @@ const cdp = createCdpController({
18
18
  postBridge,
19
19
  startPolling,
20
20
  forwardConsoleEvent,
21
+ ensureAllTabsRegistered: sessionManager.ensureAllTabsRegistered,
21
22
  })
22
23
 
23
24
  const { detachCdpTab, installCdpEventForwarder } = cdp
@@ -45,6 +46,23 @@ chrome.tabs.onRemoved.addListener((tabId) => {
45
46
 
46
47
  chrome.tabs.onActivated.addListener(({ tabId }) => {
47
48
  void sessionManager.activateTab(tabId)
49
+ void sessionManager.ensureTabRegistered(tabId, { reason: "tab_activated" }).catch(() => {})
50
+ })
51
+
52
+ chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
53
+ if (changeInfo.status !== "complete") return
54
+ void sessionManager.ensureTabRegistered(tabId, {
55
+ tab,
56
+ reason: "tab_updated_complete",
57
+ }).catch(() => {})
58
+ })
59
+
60
+ chrome.runtime.onInstalled.addListener(() => {
61
+ void sessionManager.ensureAllTabsRegistered({ reason: "extension_installed" }).catch(() => {})
62
+ })
63
+
64
+ chrome.runtime.onStartup.addListener(() => {
65
+ void sessionManager.ensureAllTabsRegistered({ reason: "browser_startup" }).catch(() => {})
48
66
  })
49
67
 
50
68
  chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
@@ -53,3 +71,5 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
53
71
  )
54
72
  return true
55
73
  })
74
+
75
+ void sessionManager.ensureAllTabsRegistered({ reason: "background_started" }).catch(() => {})
package/extension/cdp.js CHANGED
@@ -4,6 +4,7 @@ export function createCdpController({
4
4
  postBridge,
5
5
  startPolling,
6
6
  forwardConsoleEvent,
7
+ ensureAllTabsRegistered,
7
8
  }) {
8
9
  const cdpAttachedTabs = new Set()
9
10
  const cdpEnabledDomains = new Map()
@@ -159,6 +160,9 @@ export function createCdpController({
159
160
  }
160
161
 
161
162
  async function listBrowserTargets(session) {
163
+ if (typeof ensureAllTabsRegistered === "function") {
164
+ await ensureAllTabsRegistered({ reason: "list_browser_targets" }).catch(() => null)
165
+ }
162
166
  const cdpResult = await interceptTargetGetTargets(session)
163
167
  const targetInfos = Array.isArray(cdpResult?.result?.targetInfos)
164
168
  ? cdpResult.result.targetInfos