lasso-mcp 1.10.0 → 1.13.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.
Files changed (236) hide show
  1. package/README.en.md +3 -0
  2. package/README.md +5 -3
  3. package/dist/browse/StealthEngine.d.ts +36 -4
  4. package/dist/browse/StealthEngine.d.ts.map +1 -1
  5. package/dist/browse/StealthEngine.js +38 -5
  6. package/dist/browse/StealthEngine.js.map +1 -1
  7. package/dist/browse/cdp-actions.d.ts +52 -40
  8. package/dist/browse/cdp-actions.d.ts.map +1 -1
  9. package/dist/browse/cdp-actions.js +115 -94
  10. package/dist/browse/cdp-actions.js.map +1 -1
  11. package/dist/browse/markdown-extractor.d.ts +7 -0
  12. package/dist/browse/markdown-extractor.d.ts.map +1 -1
  13. package/dist/browse/markdown-extractor.js +32 -9
  14. package/dist/browse/markdown-extractor.js.map +1 -1
  15. package/dist/browse/stealth-evasions/ua-client-hints.d.ts +1 -1
  16. package/dist/browse/stealth-evasions/ua-client-hints.d.ts.map +1 -1
  17. package/dist/browse/stealth-evasions/ua-client-hints.js +2 -1
  18. package/dist/browse/stealth-evasions/ua-client-hints.js.map +1 -1
  19. package/dist/browse/stealth-profiles.d.ts +43 -12
  20. package/dist/browse/stealth-profiles.d.ts.map +1 -1
  21. package/dist/browse/stealth-profiles.js +74 -25
  22. package/dist/browse/stealth-profiles.js.map +1 -1
  23. package/dist/channels/BingChannel.d.ts +6 -0
  24. package/dist/channels/BingChannel.d.ts.map +1 -1
  25. package/dist/channels/BingChannel.js +10 -2
  26. package/dist/channels/BingChannel.js.map +1 -1
  27. package/dist/channels/BraveChannel.d.ts +10 -0
  28. package/dist/channels/BraveChannel.d.ts.map +1 -1
  29. package/dist/channels/BraveChannel.js +15 -2
  30. package/dist/channels/BraveChannel.js.map +1 -1
  31. package/dist/channels/BrowseChannel.d.ts.map +1 -1
  32. package/dist/channels/BrowseChannel.js +13 -7
  33. package/dist/channels/BrowseChannel.js.map +1 -1
  34. package/dist/channels/BrowserbaseChannel.d.ts.map +1 -1
  35. package/dist/channels/BrowserbaseChannel.js +5 -1
  36. package/dist/channels/BrowserbaseChannel.js.map +1 -1
  37. package/dist/channels/DesktopChannel.d.ts +11 -0
  38. package/dist/channels/DesktopChannel.d.ts.map +1 -1
  39. package/dist/channels/DesktopChannel.js +103 -9
  40. package/dist/channels/DesktopChannel.js.map +1 -1
  41. package/dist/channels/HeadlessChannel.d.ts +21 -2
  42. package/dist/channels/HeadlessChannel.d.ts.map +1 -1
  43. package/dist/channels/HeadlessChannel.js +47 -10
  44. package/dist/channels/HeadlessChannel.js.map +1 -1
  45. package/dist/channels/LoggedInChannel.d.ts.map +1 -1
  46. package/dist/channels/LoggedInChannel.js +2 -0
  47. package/dist/channels/LoggedInChannel.js.map +1 -1
  48. package/dist/channels/MachineMcpSearchChannel.d.ts +7 -1
  49. package/dist/channels/MachineMcpSearchChannel.d.ts.map +1 -1
  50. package/dist/channels/MachineMcpSearchChannel.js +7 -0
  51. package/dist/channels/MachineMcpSearchChannel.js.map +1 -1
  52. package/dist/channels/SearchChannel.d.ts +10 -0
  53. package/dist/channels/SearchChannel.d.ts.map +1 -1
  54. package/dist/channels/SearchChannel.js +14 -0
  55. package/dist/channels/SearchChannel.js.map +1 -1
  56. package/dist/channels/StagehandChannel.d.ts +8 -5
  57. package/dist/channels/StagehandChannel.d.ts.map +1 -1
  58. package/dist/channels/StagehandChannel.js +8 -5
  59. package/dist/channels/StagehandChannel.js.map +1 -1
  60. package/dist/channels/SteelChannel.d.ts +17 -1
  61. package/dist/channels/SteelChannel.d.ts.map +1 -1
  62. package/dist/channels/SteelChannel.js +19 -3
  63. package/dist/channels/SteelChannel.js.map +1 -1
  64. package/dist/config/config.d.ts +15 -0
  65. package/dist/config/config.d.ts.map +1 -1
  66. package/dist/config/config.js +31 -1
  67. package/dist/config/config.js.map +1 -1
  68. package/dist/desktop/AxBackend.d.ts +20 -8
  69. package/dist/desktop/AxBackend.d.ts.map +1 -1
  70. package/dist/desktop/AxBackend.js +45 -12
  71. package/dist/desktop/AxBackend.js.map +1 -1
  72. package/dist/desktop/AxProvider.d.ts +17 -11
  73. package/dist/desktop/AxProvider.d.ts.map +1 -1
  74. package/dist/desktop/AxProvider.js +61 -14
  75. package/dist/desktop/AxProvider.js.map +1 -1
  76. package/dist/desktop/CGEventProvider.d.ts +31 -2
  77. package/dist/desktop/CGEventProvider.d.ts.map +1 -1
  78. package/dist/desktop/CGEventProvider.js +102 -8
  79. package/dist/desktop/CGEventProvider.js.map +1 -1
  80. package/dist/desktop/OutlineMapper.d.ts.map +1 -1
  81. package/dist/desktop/OutlineMapper.js +2 -0
  82. package/dist/desktop/OutlineMapper.js.map +1 -1
  83. package/dist/desktop/ScreenshotVlmProvider.d.ts +45 -1
  84. package/dist/desktop/ScreenshotVlmProvider.d.ts.map +1 -1
  85. package/dist/desktop/ScreenshotVlmProvider.js +287 -14
  86. package/dist/desktop/ScreenshotVlmProvider.js.map +1 -1
  87. package/dist/desktop/desktop-doctor-checks.d.ts +1 -1
  88. package/dist/desktop/desktop-doctor-checks.d.ts.map +1 -1
  89. package/dist/desktop/desktop-doctor-checks.js +59 -2
  90. package/dist/desktop/desktop-doctor-checks.js.map +1 -1
  91. package/dist/desktop/desktop-types.d.ts +65 -1
  92. package/dist/desktop/desktop-types.d.ts.map +1 -1
  93. package/dist/desktop/desktop-types.js +14 -2
  94. package/dist/desktop/desktop-types.js.map +1 -1
  95. package/dist/doctor/creepjs-probe.d.ts.map +1 -1
  96. package/dist/doctor/creepjs-probe.js +3 -2
  97. package/dist/doctor/creepjs-probe.js.map +1 -1
  98. package/dist/doctor/doctor-cli.d.ts.map +1 -1
  99. package/dist/doctor/doctor-cli.js +3 -2
  100. package/dist/doctor/doctor-cli.js.map +1 -1
  101. package/dist/doctor/doctor.d.ts +12 -5
  102. package/dist/doctor/doctor.d.ts.map +1 -1
  103. package/dist/doctor/doctor.js +170 -34
  104. package/dist/doctor/doctor.js.map +1 -1
  105. package/dist/index.js +33 -7
  106. package/dist/index.js.map +1 -1
  107. package/dist/runtime/ToolManager.d.ts +26 -1
  108. package/dist/runtime/ToolManager.d.ts.map +1 -1
  109. package/dist/runtime/ToolManager.js +72 -1
  110. package/dist/runtime/ToolManager.js.map +1 -1
  111. package/dist/search/SearchCache.d.ts +8 -6
  112. package/dist/search/SearchCache.d.ts.map +1 -1
  113. package/dist/search/SearchCache.js +17 -13
  114. package/dist/search/SearchCache.js.map +1 -1
  115. package/dist/serp/SelectorRegistry.d.ts +1 -1
  116. package/dist/serp/SelectorRegistry.js +2 -2
  117. package/dist/serp/SelectorRegistry.js.map +1 -1
  118. package/dist/serp/SerpHealthMonitor.d.ts +2 -1
  119. package/dist/serp/SerpHealthMonitor.d.ts.map +1 -1
  120. package/dist/serp/SerpHealthMonitor.js +2 -1
  121. package/dist/serp/SerpHealthMonitor.js.map +1 -1
  122. package/dist/serp/extract.d.ts +28 -14
  123. package/dist/serp/extract.d.ts.map +1 -1
  124. package/dist/serp/extract.js +79 -11
  125. package/dist/serp/extract.js.map +1 -1
  126. package/dist/serp/selectors.d.ts +13 -5
  127. package/dist/serp/selectors.d.ts.map +1 -1
  128. package/dist/serp/selectors.js +24 -16
  129. package/dist/serp/selectors.js.map +1 -1
  130. package/dist/subprocess/McpClient.js +1 -1
  131. package/dist/subprocess/SubprocessManager.d.ts +13 -2
  132. package/dist/subprocess/SubprocessManager.d.ts.map +1 -1
  133. package/dist/subprocess/SubprocessManager.js +13 -2
  134. package/dist/subprocess/SubprocessManager.js.map +1 -1
  135. package/dist/tools/annotations.d.ts +3 -3
  136. package/dist/tools/annotations.js +3 -3
  137. package/dist/tools/descriptions.d.ts.map +1 -1
  138. package/dist/tools/descriptions.js +48 -22
  139. package/dist/tools/descriptions.js.map +1 -1
  140. package/dist/tools/desktop.d.ts.map +1 -1
  141. package/dist/tools/desktop.js +37 -1
  142. package/dist/tools/desktop.js.map +1 -1
  143. package/dist/tools/fetch-url.d.ts.map +1 -1
  144. package/dist/tools/fetch-url.js +2 -0
  145. package/dist/tools/fetch-url.js.map +1 -1
  146. package/dist/tools/network.d.ts +12 -10
  147. package/dist/tools/network.d.ts.map +1 -1
  148. package/dist/tools/network.js +14 -15
  149. package/dist/tools/network.js.map +1 -1
  150. package/dist/tools/search.d.ts +14 -2
  151. package/dist/tools/search.d.ts.map +1 -1
  152. package/dist/tools/search.js +34 -8
  153. package/dist/tools/search.js.map +1 -1
  154. package/dist/types.d.ts +13 -5
  155. package/dist/types.d.ts.map +1 -1
  156. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/00-/346/200/273/347/273/223.md +194 -0
  157. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round1-arch.md +101 -0
  158. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round1-browser.md +117 -0
  159. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round1-desktop.md +141 -0
  160. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round1-implementation.md +110 -0
  161. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round1-manual-test-checklist.md +78 -0
  162. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round1-review03.md +110 -0
  163. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round1-search.md +83 -0
  164. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round1-smoke-headless.mjs +90 -0
  165. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round1-verdict.md +252 -0
  166. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round2-arch.md +114 -0
  167. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round2-browser.md +135 -0
  168. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round2-desktop.md +130 -0
  169. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round2-manual-test-checklist.md +73 -0
  170. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round2-review03.md +147 -0
  171. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round2-search.md +109 -0
  172. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round2-verdict.md +263 -0
  173. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round3-arch.md +110 -0
  174. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round3-browser.md +123 -0
  175. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round3-desktop.md +109 -0
  176. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round3-review03.md +136 -0
  177. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round3-search.md +93 -0
  178. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round3-verdict.md +141 -0
  179. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round4-arch.md +98 -0
  180. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round4-browser.md +123 -0
  181. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round4-desktop.md +81 -0
  182. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round4-review03.md +128 -0
  183. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round4-search.md +102 -0
  184. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round4-verdict.md +85 -0
  185. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round5-arch.md +96 -0
  186. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round5-browser.md +126 -0
  187. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round5-desktop.md +90 -0
  188. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round5-search.md +115 -0
  189. package/doc/19-/346/234/200/344/274/230/346/200/247/345/256/241/346/237/245/350/275/256/346/254/241/round5-verdict.md +77 -0
  190. package/doc/KEY-GUIDE.md +2 -1
  191. package/package.json +3 -2
  192. package/src/browse/StealthEngine.ts +39 -5
  193. package/src/browse/cdp-actions.ts +145 -97
  194. package/src/browse/markdown-extractor.ts +38 -9
  195. package/src/browse/stealth-evasions/ua-client-hints.ts +2 -1
  196. package/src/browse/stealth-profiles.ts +85 -28
  197. package/src/channels/BingChannel.ts +13 -0
  198. package/src/channels/BraveChannel.ts +20 -0
  199. package/src/channels/BrowseChannel.ts +13 -7
  200. package/src/channels/BrowserbaseChannel.ts +5 -1
  201. package/src/channels/DesktopChannel.ts +103 -9
  202. package/src/channels/HeadlessChannel.ts +47 -11
  203. package/src/channels/LoggedInChannel.ts +2 -0
  204. package/src/channels/MachineMcpSearchChannel.ts +14 -0
  205. package/src/channels/SearchChannel.ts +20 -0
  206. package/src/channels/StagehandChannel.ts +8 -5
  207. package/src/channels/SteelChannel.ts +29 -2
  208. package/src/config/config.ts +40 -1
  209. package/src/desktop/AxBackend.ts +79 -10
  210. package/src/desktop/AxProvider.ts +75 -15
  211. package/src/desktop/CGEventProvider.ts +139 -10
  212. package/src/desktop/OutlineMapper.ts +2 -0
  213. package/src/desktop/ScreenshotVlmProvider.ts +323 -15
  214. package/src/desktop/desktop-doctor-checks.ts +63 -2
  215. package/src/desktop/desktop-types.ts +88 -4
  216. package/src/doctor/creepjs-probe.ts +3 -2
  217. package/src/doctor/doctor-cli.ts +6 -2
  218. package/src/doctor/doctor.ts +195 -38
  219. package/src/index.ts +40 -6
  220. package/src/invariants/check-invariants.mjs +163 -27
  221. package/src/runtime/ToolManager.ts +78 -2
  222. package/src/search/SearchCache.ts +17 -9
  223. package/src/serp/SelectorRegistry.ts +3 -3
  224. package/src/serp/SerpHealthMonitor.ts +2 -1
  225. package/src/serp/extract.ts +92 -12
  226. package/src/serp/selectors.ts +25 -17
  227. package/src/subprocess/McpClient.ts +1 -1
  228. package/src/subprocess/SubprocessManager.ts +13 -2
  229. package/src/tools/annotations.ts +3 -3
  230. package/src/tools/descriptions.ts +48 -22
  231. package/src/tools/desktop.ts +37 -1
  232. package/src/tools/fetch-url.ts +2 -0
  233. package/src/tools/network.ts +19 -18
  234. package/src/tools/search.ts +34 -6
  235. package/src/types.ts +14 -5
  236. package/vitest.workspace.ts +4 -0
package/README.en.md CHANGED
@@ -40,6 +40,7 @@ Twin star of [media-gen-mcp](https://github.com/wangdong233/media-gen-mcp) (the
40
40
  | You say …… | You get |
41
41
  |---|---|
42
42
  | "Search for the latest on the rust async ecosystem" | Structured search results (auto-switches to the next engine if one is down — you don't feel a thing) |
43
+ | "Search Claude Code updates from the last week" (v1.11) | Time-filtered results via `freshness=week` — no hand-written dates in the query |
43
44
  | "Grab the text of the github.com homepage" | Clean article text (nav bars / ads / clutter stripped — saves 30–70% on tokens) |
44
45
  | "Open my logged-in Jira and show my to-dos" | A snapshot of the logged-in page (reuses your local Chrome; you handle 2FA yourself) |
45
46
  | "This link is dead, find an archive" | The most recent snapshot from the Internet Archive |
@@ -189,6 +190,8 @@ Goes to the Internet Archive (Wayback Machine) to find the last archived copy of
189
190
 
190
191
  ## Install
191
192
 
193
+ **Current version v1.11.0** (the "everything grab handle" implementation gap closed: **desktop goes from observe-only to full act** — `desktop` click/type/scroll now really execute (AXAPI semantic clicks + write-then-read-back verification + honest stale-ref errors), plus coordinate mouse actions (drag/wheel/move as canvas/Electron fallback) and a `skeleton` tree-pruning option (big token savings on dense apps); **driver layer upgraded chrome-devtools-mcp 0.3.0 → 1.7.0** (11 months / 57 releases of fixes; launch-level stealth UA/viewport; upstream telemetry explicitly disabled); **search gained a `freshness` time filter** (day/week/month/year passed through to all three engines — no more hand-writing dates into queries for news/release tracking); the zero-key English fallback switched from Baidu to DuckDuckGo; new `LASSO_PROXY` browser egress proxy (affects headless/cloud browsers only — your logged-in Chrome's egress stays untouched).)
194
+
192
195
  **Prerequisites**: Node.js ≥ 20; Claude Code (or any MCP-capable client).
193
196
 
194
197
  ```bash
package/README.md CHANGED
@@ -40,10 +40,12 @@
40
40
  | 你说 …… | 你得到 |
41
41
  |---|---|
42
42
  | 「搜一下 rust async 生态最新动态」 | 结构化搜索结果(某家临时挂掉自动换下一家,你无感) |
43
- | 「抓一下 github.com 首页文字」 | 干净正文(自动剥掉导航 / 广告 / 冗余,省 30–70% 字数) |
43
+ | 「搜最近一周 Claude Code 的更新」(v1.11) | `freshness=week` 过滤的时效结果——不用往查询词里手写日期 |
44
+ | 「抓一下 github.com 首页文字」 | 干净正文(自动剥掉导航 / 广告 / 冗余,省 30–70% 字数;28 个高频站点走专用抽取器、表格不丢结构——v1.12) |
44
45
  | 「打开我已登录的 Jira 看看待办」 | 登录态页面快照(复用你本机 Chrome,2FA 你自己解) |
45
46
  | 「这个链接打不开了,找找存档」 | 互联网档案馆最近一份快照 |
46
- | 「把 Finder 当前窗口的文件列出来」 | 桌面上的窗口和控件列表(语义树,非截图) |
47
+ | 「把 Finder 当前窗口的文件列出来」 | 桌面上的窗口和控件列表(语义树,非截图;树被截断会明说 `truncated:true`——v1.12) |
48
+ | 「点一下那个新建文件夹按钮」「在搜索框里输入 XX」(v1.11) | 桌面动作真实执行(AXAPI 语义点击/输入 + 结果验证;canvas/Electron 自动降级坐标点击) |
47
49
  | 「把这一页截个整页长图」「存成 PDF」 | 落盘的文件路径(不会把一大坨图片数据塞进对话) |
48
50
  | 「这个页面加载了哪些第三方跟踪」 | 资源列表 + 跟踪域名计数 |
49
51
  | 「列一下我现在能控的所有窗口和网页」 | 一个统一清单(网页和桌面窗口都在里面) |
@@ -190,7 +192,7 @@ macOS 上能控 Finder / Mail / Safari / Notes / 系统设置等任何原生 app
190
192
 
191
193
  ## 安装
192
194
 
193
- **当前版本 v1.10.0**(v1.10 浏览器默认静默 + 用完即关:`launch-chrome` 默认零窗口零打扰启动(macOS/Windows 适配,`--mode visible` 可回退)、恒带后台反节流与静音、server 运行期最后使用后 ~60 秒自动关闭(`LASSO_LAUNCH_IDLE_MS` 可调,5 分钟语义配 300000 保留);v1.9 补上浏览器生命周期收尾:无头浏览器空闲 5 分钟自动回收、`lasso chrome-stop` 按台账关闭 Lasso 起的 Chrome、`tab_restore` 恢复你原来的 tab 列表——见上文「用完怎么收尾」;v1.8 修复了 wave1 全量实测暴露的 24 条缺陷:上游 chrome-devtools-mcp@0.3.0 契约适配、截图真实落盘、launch-chrome 探活、caller-tier 配额接线、`read_text` 续页工具等——完整清单见 [doc/17-功能测试清单.md](doc/17-功能测试清单.md) 的「v1.8 修复记录」)。
195
+ **当前版本 v1.13.0**(v1.13 实施层调优 7 项(最优性审查第 3 轮):**无头浏览器语言指纹一致**——HTTP `Accept-Language` 头现随 stealth 档案下发(此前发宿主真值,中文机器上配英文档案会露出「头 zh-CN ↔ 页面 en-US」的自相矛盾);`navigator.languages` 同步改为档案感知;**VLM 截图带区域时的落点修复**——`screenshot_region` 场景下 VLM 推断坐标自动换算回全屏坐标(此前系统性偏移一个区域原点的距离、还报成功);**`desktop find` 拒绝纯 ref 查询**——`where` 只认 text/role,纯 ref 查询诚实报 invalid_params(此前静默退化成全树命中,token 爆炸还装成功);**退出更快更稳**——Steel 会话释放加 3 秒上界(自托管 Steel 停摆时 CC 退出不再最长卡 5 分钟);VLM 档遇 macOS 输入合成权限缺失时明确报「需要授权」而非含糊失败;v1.12 实施层调优 14 项(最优性审查第 2 轮):**markdown 抽取双激活**——defuddle 站点专用抽取器(HN/Reddit/GitHub/Wikipedia/Substack/Medium 等 28 站)+ 表格/数学结构保真转换(GFM 表格不再丢结构;相对链接自动绝对化;输出可能含 Obsidian 方言如 `==高亮==`、`[^N]` 脚注);**无头浏览器默认指纹与宿主系统对齐**——macOS 上默认 macOS Chrome 指纹(消除「UA 说 Windows、client hints 招供 macOS」的矛盾,doctor 会提示与已装 Chrome 的版本偏差);**桌面链尾诚实化**——VLM 截图推断不再谎报成功(能执行则真执行、不能则诚实 unknown)、`wait/expect` 需连续两次命中才算(加载闪现元素不再假成功)、`snapshot` 截断时顶层 `truncated:true`、`find` 命中节点附可执行动作清单;**Electron 输入框修复**——吞 AXSetValue 的控件(Slack/VSCode 等)type 自动降级为「聚焦 + 键盘合成」(ASCII);**拖拽变可用**——按下 200ms + 12 点插值轨迹 + 沉淀 100ms(滑条/拖拽排序从大概率失败变可用);**freshness 全链一致**——machine_mcp 与 DuckDuckGo 兜底不再静默丢弃时效参数;CC 异常退出时 Lasso 进程即时收尾(此前最长悬挂 1 小时);v1.11「全交互抓手」实施维度补齐:**桌面从「能看」变「能点」**——`desktop` 的 click/type/scroll 真正落地(AXAPI 语义点击 + 写后读回验证 + 过期引用诚实报错),并新增坐标鼠标动作(拖拽/滚轮/移动,canvas/Electron 兜底)和 `skeleton` 树剪枝(密集应用 token 大幅下降);**驱动层升级 chrome-devtools-mcp 0.3.0 → 1.7.0**(11 个月 57 版红利;启动级反检测 UA/视口;已默认关闭上游遥测);**search 新增 `freshness` 时效过滤**(day/week/month/year 透传全部引擎,查新闻/版本动向不再往查询词里手写日期);英文查询的零 Key 兜底从百度换成 DuckDuckGo;新增 `LASSO_PROXY` 浏览器出口代理(只影响无头/云浏览器,登录态 Chrome 出口不动);v1.10 浏览器默认静默 + 用完即关:`launch-chrome` 默认零窗口零打扰启动(macOS/Windows 适配,`--mode visible` 可回退)、恒带后台反节流与静音、server 运行期最后使用后 ~60 秒自动关闭(`LASSO_LAUNCH_IDLE_MS` 可调,5 分钟语义配 300000 保留);v1.9 补上浏览器生命周期收尾:无头浏览器空闲 5 分钟自动回收、`lasso chrome-stop` 按台账关闭 Lasso 起的 Chrome、`tab_restore` 恢复你原来的 tab 列表——见上文「用完怎么收尾」;v1.8 修复了 wave1 全量实测暴露的 24 条缺陷:上游 chrome-devtools-mcp@0.3.0 契约适配、截图真实落盘、launch-chrome 探活、caller-tier 配额接线、`read_text` 续页工具等——完整清单见 [doc/17-功能测试清单.md](doc/17-功能测试清单.md) 的「v1.8 修复记录」)。
194
196
 
195
197
  **前提**:Node.js ≥ 20;Claude Code(或任何支持 MCP 的客户端)。
196
198
 
@@ -23,7 +23,7 @@
23
23
  * (Argus 范式,F3.4.6 政策红线)
24
24
  */
25
25
  import type { McpClient } from "../subprocess/McpClient.js";
26
- import { type StealthProfileName } from "./stealth-profiles.js";
26
+ import { type StealthProfileName, type StealthProfile } from "./stealth-profiles.js";
27
27
  export declare class StealthEngine {
28
28
  /**
29
29
  * 在 navigate 前注入 stealth profile(CDP methods 直调 + evaluate_script)。
@@ -31,7 +31,8 @@ export declare class StealthEngine {
31
31
  * v1.5 流程(parse13 §3.1 + §4.5):
32
32
  * 1. profile 校验(未知 profile 名 → throw;caller catch 走 didnt)
33
33
  * 2. evaluate_script(buildUserAgentOverrideScript) → navigator.userAgent / platform /
34
- * language 改写(**先执行**,使后续 UA client hints 能读到正确 Chrome 版本)
34
+ * language / languages 改写(**先执行**,使后续 UA client hints 能读到正确 Chrome
35
+ * 版本;languages 自 T3-1 profile 感知,与 language 同源同值)
35
36
  * 3. evaluate_script(STEALTH_INJECTION_SCRIPT 16 路) → webdriver / languages / permissions /
36
37
  * chrome.runtime/app/csi/loadTimes / plugins / vendor / hardwareConcurrency / media.codecs /
37
38
  * webgl.vendor / iframe.contentWindow / outerdimensions / userAgentData(brands 版本与
@@ -43,8 +44,12 @@ export declare class StealthEngine {
43
44
  * (secChUa / secFetch* / accept*)已定义在 StealthProfile 顶级 const(INV-30),供后续
44
45
  * chrome-devtools-mcp 暴露 header 注入工具时直用。
45
46
  *
46
- * 注:viewport / timezone 由 chrome-devtools-mcp 启动 flag 控制
47
- * (subprocess spec --window-size / --timezone);StealthEngine 不在这里设。
47
+ * 注:viewport chrome-devtools-mcp 启动 flag `--viewport=` 控制(HeadlessChannel
48
+ * spec 构造期拼入);timezone **无启动 flag**(上游 1.7.0 CLI 32 项无此选项,
49
+ * Chrome 亦无此开关)——profile.timezone 是档案字段、无行为消费,页面 Intl
50
+ * 跟随宿主(与宿主 IP 自洽的诚实形态);StealthEngine 不在这里设。
51
+ * (T3-5 round3 注释归真:此前「--window-size / --timezone」双失实已修正——
52
+ * 真实 flag 名是 --viewport=,且 spec 从无 timezone flag。)
48
53
  *
49
54
  * @param client McpClient(chrome-devtools-mcp connection)
50
55
  * @param profileName STEALTH_PROFILES 顶级 const 的 key
@@ -97,4 +102,31 @@ export declare class StealthEngine {
97
102
  * (会产生 `() => { () => ... }` 的非法语句)。
98
103
  */
99
104
  export declare function toFnExpression(script: string): string;
105
+ /**
106
+ * T3-1(round3 v1.13):profile.language → navigator.languages 值。
107
+ *
108
+ * 真实浏览器 navigator.languages 与 navigator.language / Accept-Language 头
109
+ * 同源同值(主标签在前 + 主子标签兜底)——旧 CORE 硬编码 ["en-US","en"] 在
110
+ * zh-CN 宿主 / 非 en-US profile 下产生「头 zh-CN ↔ JS en-US」的自然不可能形状
111
+ * (与 T2-1 所修 OS 矛盾同族)。派生规则:[language, language 的主子标签]。
112
+ *
113
+ * @returns 恰好 2 元素(真实浏览器同款形状;acceptLanguage 主 token 与此一致)
114
+ */
115
+ export declare function profileLanguages(language: string): [string, string];
116
+ /**
117
+ * 构造 navigator.userAgent / platform / language / languages override 注入脚本。
118
+ *
119
+ * 设计:脚本是纯字符串拼装(无副作用),profile 字段经 JSON.stringify
120
+ * 转义防注入(profile 是顶级 const 数据,本就是 trusted,但仍走 JSON.stringify
121
+ * 守编码正确性 —— 守 02 §4 简单性:用对的语言做对的事)。
122
+ *
123
+ * T3-1(round3 v1.13):navigator.languages 从 CORE_STEALTH_SCRIPT #2 硬编码
124
+ * ["en-US","en"] 迁入此处(profile 感知;CORE 原位置留注释指路,16 路计数不变)。
125
+ * 本脚本先于 STEALTH_INJECTION_SCRIPT 执行(W1-DEF-1 顺序),languages 在任何
126
+ * 页面 JS 读取前已就位。
127
+ *
128
+ * round3-review03:导出供 doctor #25 stealth_profile_self_check 逐 profile 校验
129
+ * (languages 反检测点的真 producer 在此,不在 CORE 注释——L0 证据升级 L1)。
130
+ */
131
+ export declare function buildUserAgentOverrideScript(profile: StealthProfile): string;
100
132
  //# sourceMappingURL=StealthEngine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StealthEngine.d.ts","sourceRoot":"","sources":["../../src/browse/StealthEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,EAKL,KAAK,kBAAkB,EAExB,MAAM,uBAAuB,CAAC;AAK/B,qBAAa,aAAa;IACxB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,aAAa,CACjB,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,kBAAkB,GAC9B,OAAO,CAAC,IAAI,CAAC;IA4ChB;;;;;;;;;OASG;IACG,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAwBpE;;;;;;;;;;;OAWG;IACH,oBAAoB,CAAC,MAAM,EAAE,qBAAqB,GAAG,uBAAuB,GAAG;QAC7E,OAAO,EAAE,OAAO,CAAC;QACjB,gBAAgB,EAAE,MAAM,CAAC;QACzB,KAAK,EAAE,MAAM,CAAC;KACf;IAoBD;;;;;;;;OAQG;YACW,QAAQ;CA6BvB;AAKD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD"}
1
+ {"version":3,"file":"StealthEngine.d.ts","sourceRoot":"","sources":["../../src/browse/StealthEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAK/B,qBAAa,aAAa;IACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACG,aAAa,CACjB,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,kBAAkB,GAC9B,OAAO,CAAC,IAAI,CAAC;IA4ChB;;;;;;;;;OASG;IACG,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAwBpE;;;;;;;;;;;OAWG;IACH,oBAAoB,CAAC,MAAM,EAAE,qBAAqB,GAAG,uBAAuB,GAAG;QAC7E,OAAO,EAAE,OAAO,CAAC;QACjB,gBAAgB,EAAE,MAAM,CAAC;QACzB,KAAK,EAAE,MAAM,CAAC;KACf;IAoBD;;;;;;;;OAQG;YACW,QAAQ;CA6BvB;AAKD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAKD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAGnE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CA4B5E"}
@@ -11,7 +11,8 @@ export class StealthEngine {
11
11
  * v1.5 流程(parse13 §3.1 + §4.5):
12
12
  * 1. profile 校验(未知 profile 名 → throw;caller catch 走 didnt)
13
13
  * 2. evaluate_script(buildUserAgentOverrideScript) → navigator.userAgent / platform /
14
- * language 改写(**先执行**,使后续 UA client hints 能读到正确 Chrome 版本)
14
+ * language / languages 改写(**先执行**,使后续 UA client hints 能读到正确 Chrome
15
+ * 版本;languages 自 T3-1 profile 感知,与 language 同源同值)
15
16
  * 3. evaluate_script(STEALTH_INJECTION_SCRIPT 16 路) → webdriver / languages / permissions /
16
17
  * chrome.runtime/app/csi/loadTimes / plugins / vendor / hardwareConcurrency / media.codecs /
17
18
  * webgl.vendor / iframe.contentWindow / outerdimensions / userAgentData(brands 版本与
@@ -23,8 +24,12 @@ export class StealthEngine {
23
24
  * (secChUa / secFetch* / accept*)已定义在 StealthProfile 顶级 const(INV-30),供后续
24
25
  * chrome-devtools-mcp 暴露 header 注入工具时直用。
25
26
  *
26
- * 注:viewport / timezone 由 chrome-devtools-mcp 启动 flag 控制
27
- * (subprocess spec --window-size / --timezone);StealthEngine 不在这里设。
27
+ * 注:viewport chrome-devtools-mcp 启动 flag `--viewport=` 控制(HeadlessChannel
28
+ * spec 构造期拼入);timezone **无启动 flag**(上游 1.7.0 CLI 32 项无此选项,
29
+ * Chrome 亦无此开关)——profile.timezone 是档案字段、无行为消费,页面 Intl
30
+ * 跟随宿主(与宿主 IP 自洽的诚实形态);StealthEngine 不在这里设。
31
+ * (T3-5 round3 注释归真:此前「--window-size / --timezone」双失实已修正——
32
+ * 真实 flag 名是 --viewport=,且 spec 从无 timezone flag。)
28
33
  *
29
34
  * @param client McpClient(chrome-devtools-mcp connection)
30
35
  * @param profileName STEALTH_PROFILES 顶级 const 的 key
@@ -179,13 +184,35 @@ export function toFnExpression(script) {
179
184
  // buildUserAgentOverrideScript(profile-specific payload builder)
180
185
  // ============================================================
181
186
  /**
182
- * 构造 navigator.userAgent / platform / language override 注入脚本。
187
+ * T3-1(round3 v1.13):profile.language navigator.languages 值。
188
+ *
189
+ * 真实浏览器 navigator.languages 与 navigator.language / Accept-Language 头
190
+ * 同源同值(主标签在前 + 主子标签兜底)——旧 CORE 硬编码 ["en-US","en"] 在
191
+ * zh-CN 宿主 / 非 en-US profile 下产生「头 zh-CN ↔ JS en-US」的自然不可能形状
192
+ * (与 T2-1 所修 OS 矛盾同族)。派生规则:[language, language 的主子标签]。
193
+ *
194
+ * @returns 恰好 2 元素(真实浏览器同款形状;acceptLanguage 主 token 与此一致)
195
+ */
196
+ export function profileLanguages(language) {
197
+ const primary = language.split("-")[0].toLowerCase();
198
+ return [language, primary];
199
+ }
200
+ /**
201
+ * 构造 navigator.userAgent / platform / language / languages override 注入脚本。
183
202
  *
184
203
  * 设计:脚本是纯字符串拼装(无副作用),profile 字段经 JSON.stringify
185
204
  * 转义防注入(profile 是顶级 const 数据,本就是 trusted,但仍走 JSON.stringify
186
205
  * 守编码正确性 —— 守 02 §4 简单性:用对的语言做对的事)。
206
+ *
207
+ * T3-1(round3 v1.13):navigator.languages 从 CORE_STEALTH_SCRIPT #2 硬编码
208
+ * ["en-US","en"] 迁入此处(profile 感知;CORE 原位置留注释指路,16 路计数不变)。
209
+ * 本脚本先于 STEALTH_INJECTION_SCRIPT 执行(W1-DEF-1 顺序),languages 在任何
210
+ * 页面 JS 读取前已就位。
211
+ *
212
+ * round3-review03:导出供 doctor #25 stealth_profile_self_check 逐 profile 校验
213
+ * (languages 反检测点的真 producer 在此,不在 CORE 注释——L0 证据升级 L1)。
187
214
  */
188
- function buildUserAgentOverrideScript(profile) {
215
+ export function buildUserAgentOverrideScript(profile) {
189
216
  // W1-DEF-1(v1.8):函数表达式(上游 0.3.0 契约),不再传 IIFE 语句串。
190
217
  return `() => {
191
218
  try {
@@ -206,6 +233,12 @@ function buildUserAgentOverrideScript(profile) {
206
233
  configurable: true,
207
234
  });
208
235
  } catch (e) {}
236
+ try {
237
+ Object.defineProperty(navigator, "languages", {
238
+ get: function() { return ${JSON.stringify(profileLanguages(profile.language))}; },
239
+ configurable: true,
240
+ });
241
+ } catch (e) {}
209
242
  }`;
210
243
  }
211
244
  function firstText(r) {
@@ -1 +1 @@
1
- {"version":3,"file":"StealthEngine.js","sourceRoot":"","sources":["../../src/browse/StealthEngine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"StealthEngine.js","sourceRoot":"","sources":["../../src/browse/StealthEngine.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,GAG3B,MAAM,uBAAuB,CAAC;AAE/B,+DAA+D;AAC/D,gBAAgB;AAChB,+DAA+D;AAC/D,MAAM,OAAO,aAAa;IACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,KAAK,CAAC,aAAa,CACjB,MAAiB,EACjB,WAA+B;QAE/B,MAAM,OAAO,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,2BAA2B,WAAW,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,+EAA+E;QAC/E,8DAA8D;QAC9D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAC9B,MAAM,EACN,4BAA4B,CAAC,OAAO,CAAC,EACrC,0BAA0B,CAC3B,CAAC;QAEF,uEAAuE;QACvE,sEAAsE;QACtE,gEAAgE;QAChE,iCAAiC;QACjC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAChC,MAAM,EACN,cAAc,CAAC,wBAAwB,CAAC,EACxC,qBAAqB,CACtB,CAAC;QAEF,2DAA2D;QAC3D,iEAAiE;QACjE,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC;gBACV,GAAG,EAAE,uBAAuB;gBAC5B,OAAO,EAAE,WAAW;gBACpB,cAAc,EAAE,IAAI;gBACpB,iBAAiB,EAAE,MAAM;aAC1B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,CAAC,IAAI,CAAC;YACV,GAAG,EAAE,kBAAkB;YACvB,OAAO,EAAE,WAAW;YACpB,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK;YAC1C,KAAK,EAAE,EAAE;SACV,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,yBAAyB,CAAC,MAAiB;QAC/C,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE;gBAClD,QAAQ,EAAE,2BAA2B;aACtC,CAAC,CAAkB,CAAC;YACrB,uDAAuD;YACvD,2BAA2B;YAC3B,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,kDAAkD;YAClD,MAAM,CAAC,IAAI,CAAC;gBACV,GAAG,EAAE,mCAAmC;gBACxC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;aACjB,CAAC,CAAC;YACH,OAAO,KAAK,CAAC;QACf,CAAC;QACD,oCAAoC;QACpC,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QACvC,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,OAAO;YAAE,OAAO,KAAK,CAAC;QACzC,oBAAoB;QACpB,OAAO,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;;;;;;OAWG;IACH,oBAAoB,CAAC,MAAuD;QAK1E,MAAM,KAAK,GACT,MAAM,KAAK,qBAAqB;YAC9B,CAAC,CAAC,iDAAiD;YACnD,CAAC,CAAC,qCAAqC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC;YACV,GAAG,EAAE,gCAAgC;YACrC,MAAM;YACN,KAAK;SACN,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,OAAO;YAChB,gBAAgB,EAAE,0BAA0B;YAC5C,KAAK;SACN,CAAC;IACJ,CAAC;IAED,+DAA+D;IAC/D,YAAY;IACZ,+DAA+D;IAC/D;;;;;;;;OAQG;IACK,KAAK,CAAC,QAAQ,CACpB,MAAiB,EACjB,MAAc,EACd,GAAW;QAEX,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE;gBAClD,QAAQ,EAAE,MAAM;aACjB,CAAC,CAAkB,CAAC;YACrB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;gBACf,uEAAuE;gBACvE,oCAAoC;gBACpC,MAAM,CAAC,IAAI,CAAC;oBACV,GAAG,EAAE,WAAW,GAAG,SAAS;oBAC5B,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,mBAAmB;iBAC3C,CAAC,CAAC;gBACH,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,uEAAuE;YACvE,oCAAoC;YACpC,MAAM,CAAC,IAAI,CAAC;gBACV,GAAG,EAAE,WAAW,GAAG,SAAS;gBAC5B,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;aACjB,CAAC,CAAC;YACH,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF;AAED,+DAA+D;AAC/D,kCAAkC;AAClC,+DAA+D;AAC/D;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO,YAAY,MAAM,KAAK,CAAC;AACjC,CAAC;AAED,+DAA+D;AAC/D,iEAAiE;AACjE,+DAA+D;AAC/D;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC;IACtD,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,4BAA4B,CAAC,OAAuB;IAClE,kDAAkD;IAClD,OAAO;;;iCAGwB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC;;;;;;iCAMjC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC;;;;;;iCAMhC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC;;;;;;iCAMhC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;;;;EAIjF,CAAC;AACH,CAAC;AAQD,SAAS,SAAS,CAAC,CAA4B;IAC7C,IAAI,CAAC,CAAC,EAAE,OAAO;QAAE,OAAO,SAAS,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC;IACjD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -42,16 +42,20 @@ export declare const CDP_UPSTREAM_TOOL_NAMES: Readonly<{
42
42
  /** chrome-devtools-mcp `pdf` 工具(CDP Page.printToPDF;Go/No-Go F1 探测点) */
43
43
  pdf: "pdf";
44
44
  /**
45
- * chrome-devtools-mcp network 资源抓取工具(v0.5 MVP 走 evaluate_script 注入
46
- * PerformanceObserver 兜底;上游若暴露专门工具则切换。Go/No-Go F2 探测点)。
45
+ * chrome-devtools-mcp network 抓取工具。
46
+ * v1.11(round1 T5):0.3.0 时代走 evaluate_script 注 PerformanceObserver(F2 已知
47
+ * 限制:proxy/TUN 改 timing 抓不全);1.7.0 暴露原生 list_network_requests /
48
+ * get_network_request(CDP Network 域)→ 直调原生工具,注入路径删除。
47
49
  */
48
- network_log: "network_log";
50
+ network_log: "list_network_requests";
51
+ /** 单请求详情(响应体/头/时序;1.7.0 原生) */
52
+ network_get: "get_network_request";
49
53
  /**
50
- * chrome-devtools-mcp console 日志工具(上游若不暴露则 doConsole 走 evaluate 注入兜底)。
51
- * v0.5 M0.5b 暂不接入 console 工具实装(占位;M0.5c network 时统一上线)。
54
+ * chrome-devtools-mcp console 抓取工具(1.7.0 原生 list_console_messages)。
55
+ * v1.11(round1 T5):从 v0.5 M0.5b 占位变实装。
52
56
  */
53
- console_log: "console_log";
54
- /** evaluate_script(既有 doEvaluate 在 BrowseChannel.ts;此处仅记录名用于 doConsole/doNetwork 兜底) */
57
+ console_log: "list_console_messages";
58
+ /** evaluate_script(既有 doEvaluate 在 BrowseChannel.ts;此处仅记录名用于历史探测) */
55
59
  evaluate_script: "evaluate_script";
56
60
  }>;
57
61
  /**
@@ -78,47 +82,55 @@ export declare function doPdf(c: McpClient, _url: string, opts: BrowseOptions):
78
82
  /**
79
83
  * network action handler —— 经 BrowseChannel.actionDispatch Map 追加(INV-33)。
80
84
  *
81
- * 实现路径(parse6 §3.4 + §4.4 + §7.1 F2):
82
- * - v0.5 MVP evaluate_script 注入 PerformanceObserver(JS-level 抓取)
83
- * - 上游 chrome-devtools-mcp 若暴露专门 `network_log` 工具(doctor 探测),v0.6+ 切换
84
- * - JS-level 抓取的已知限制(F2):proxy / TUN 透明代理改 timing 时可能抓不全;
85
- * network.ts 工具层会在低计数时挂 data.next_step 提示(不阻断 worked outcome)
85
+ * v1.11(round1 T5):0.3.0 时代的 evaluate_script 注入 PerformanceObserver 路径
86
+ * **删除**,改调 1.7.0 原生 `list_network_requests`(CDP Network 域采集):
87
+ * - 数据完整度:method/status 全量(不再受 fake-ip TUN timing 抓不全影响——F2 关闭)
88
+ * - browse 流程 NAV_FIRST_ACTIONS 先导航 上游采「最近一次导航以来」的请求,
89
+ * navigate-first 流程 1:1 契合
90
+ *
91
+ * 上游响应(1.7.0 McpResponse 文本渲染,NetworkFormatter concise 格式):
92
+ * - `## Network requests` 头 + 分页信息行 + 每请求一行
93
+ * `reqid=<N> <METHOD> <url> [<status>]`(可能带 ` [selected ...]` 后缀)
94
+ * - 按行正则抽取(upstream-response.ts 围栏提取同范式)。
86
95
  *
87
96
  * opts(BrowseOptions.network_*):
88
- * - network_filter : "xhr" | "fetch" | "img" | "3rd-party" | "all"(默认 "all";过滤在
89
- * network.ts 工具层做,doNetwork 抓全量让工具层决定)
90
- * - network_include_bodies : boolean(v0.5 不实装;schema forward-compat)
91
- * - network_timeout_ms : number(默认 3000ms;PerformanceObserver 采集窗口)
92
- *
93
- * 注入脚本(与 parse6 §3.4.2 伪码逐行对齐):
94
- * - new PerformanceObserver((list) => { for (e of list.getEntries()) entries.push({
95
- * name: e.name, type: e.initiatorType, duration: e.duration,
96
- * ttfb: e.responseStart - e.requestStart, bytes: e.transferSize,
97
- * workerStart: e.workerStart
98
- * }) })
99
- * - obs.observe({ type: "resource", buffered: true }) // buffered=true 拉历史 + 后续
100
- * - setTimeout(() => { obs.disconnect(); resolve(JSON.stringify(entries)); }, timeout_ms)
101
- *
102
- * @returns Partial<BrowseResult>:preview 字段含 entries JSON 字符串
103
- * (network.ts 工具层会把它过 applyOutputEnvelope;INV-34 同源)
97
+ * - network_filter : "xhr"|"fetch"|"img"|"3rd-party"|"all" → 映射上游 resourceTypes
98
+ * (xhr→xhr / fetch→fetch / img→image;3rd-party/all 全量,
99
+ * 3rd-party 判定在 network.ts 工具层)
100
+ * - network_timeout_ms / network_include_bodies:不再适用(原生工具即时返回);
101
+ * 字段保留(zod 契约稳定),值被忽略
102
+ *
103
+ * @returns Partial<BrowseResult>:preview = entries JSON 字符串(network.ts 工具层
104
+ * filterResources + applyOutputEnvelope;INV-34 同源)
104
105
  */
105
106
  export declare function doNetwork(c: McpClient, _url: string, opts: BrowseOptions): Promise<Partial<BrowseResult>>;
107
+ /** 1.7.0 list_network_requests 文本行 → 结构化条目(围栏提取范式)。 */
108
+ export declare function parseNetworkRequestLines(text: string): Array<{
109
+ name: string;
110
+ type: string;
111
+ reqid: number;
112
+ method: string;
113
+ status: string;
114
+ }>;
106
115
  /**
107
116
  * console action handler —— 经 BrowseChannel.actionDispatch Map 追加(INV-33)。
108
117
  *
109
- * v0.5 M0.5b 立场:占位实装 —— parse6 §2.1 把 console entry 加入 dispatch Map(INV-33
110
- * 要求三 action 必在 Map),但 M0.5b 阶段不实装真正 console 日志抓取(推 M0.5c network
111
- * 时统一上线 evaluate_script 注入范式 + 3rd-party 过滤等)。
118
+ * v1.11(round1 T5):从占位("v0.5 M0.5b placeholder")变实装——调 1.7.0 原生
119
+ * `list_console_messages`。
112
120
  *
113
- * R-CI-02:不在本函数返回特殊形状;与既有 doEvaluate 同档 throw(无 js 时 throw)
114
- * BrowseChannel.browse() classifyBrowseError outcome=unknown
115
- * 上层(暂无 console.ts 工具)未来 console.ts 工具会包装成 outcome=didnt
116
- * + retrieval_method=console_not_implemented_in_v0.5 + next_step。
121
+ * 上游响应(ConsoleFormatter concise 格式):
122
+ * - `## Console messages` + 每消息一行
123
+ * `msgid=<N> [<type>] <text> (<N> args)`(可能带 ` [N times]` 后缀)
117
124
  *
118
- * 设计:本占位**永不抛错**(return + preview 而非 throw),让 BrowseChannel.browse()
119
- * outcome=worked + retrieval_method=chrome_devtools_mcp_console_placeholder。
120
- * 这样 INV-33 断言("console" 必须在 dispatch Map)落地,且不影响任何现有调用路径
121
- * (v0.5 没有 console tool 注册;只是 Map entry 预留)。
125
+ * @returns Partial<BrowseResult>:preview = messages JSON 字符串
122
126
  */
123
- export declare function doConsole(_c: McpClient, _url: string, _opts: BrowseOptions): Promise<Partial<BrowseResult>>;
127
+ export declare function doConsole(c: McpClient, _url: string, _opts: BrowseOptions): Promise<Partial<BrowseResult>>;
128
+ /** 1.7.0 list_console_messages 文本行 → 结构化消息。 */
129
+ export declare function parseConsoleMessageLines(text: string): Array<{
130
+ id: number;
131
+ type: string;
132
+ text: string;
133
+ argsCount: number;
134
+ count?: number;
135
+ }>;
124
136
  //# sourceMappingURL=cdp-actions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cdp-actions.d.ts","sourceRoot":"","sources":["../../src/browse/cdp-actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK/D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB;IAClC,wEAAwE;;IAExE;;;OAGG;;IAEH;;;OAGG;;IAEH,wFAAwF;;EAExF,CAAC;AAWH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,KAAK,CACzB,CAAC,EAAE,SAAS,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAsChC;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,SAAS,CAC7B,CAAC,EAAE,SAAS,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAgEhC;AAKD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,SAAS,CAC7B,EAAE,EAAE,SAAS,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAOhC"}
1
+ {"version":3,"file":"cdp-actions.d.ts","sourceRoot":"","sources":["../../src/browse/cdp-actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK/D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB;IAClC,wEAAwE;;IAExE;;;;;OAKG;;IAEH,+BAA+B;;IAE/B;;;OAGG;;IAEH,qEAAqE;;EAErE,CAAC;AAwBH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,KAAK,CACzB,CAAC,EAAE,SAAS,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAsChC;AAKD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,SAAS,CAC7B,CAAC,EAAE,SAAS,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAiChC;AAED,uDAAuD;AACvD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAqBD;AAKD;;;;;;;;;;;GAWG;AACH,wBAAsB,SAAS,CAC7B,CAAC,EAAE,SAAS,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAgBhC;AAED,+CAA+C;AAC/C,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5D,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAuBD"}
@@ -1,4 +1,3 @@
1
- import { parseEvalResult } from "./upstream-response.js";
2
1
  // ============================================================
3
2
  // 顶级 const:chrome-devtools-mcp 上游工具名集中表(parse6 §4.4 决策)
4
3
  // ============================================================
@@ -17,18 +16,34 @@ export const CDP_UPSTREAM_TOOL_NAMES = Object.freeze({
17
16
  /** chrome-devtools-mcp `pdf` 工具(CDP Page.printToPDF;Go/No-Go F1 探测点) */
18
17
  pdf: "pdf",
19
18
  /**
20
- * chrome-devtools-mcp network 资源抓取工具(v0.5 MVP 走 evaluate_script 注入
21
- * PerformanceObserver 兜底;上游若暴露专门工具则切换。Go/No-Go F2 探测点)。
19
+ * chrome-devtools-mcp network 抓取工具。
20
+ * v1.11(round1 T5):0.3.0 时代走 evaluate_script 注 PerformanceObserver(F2 已知
21
+ * 限制:proxy/TUN 改 timing 抓不全);1.7.0 暴露原生 list_network_requests /
22
+ * get_network_request(CDP Network 域)→ 直调原生工具,注入路径删除。
22
23
  */
23
- network_log: "network_log",
24
+ network_log: "list_network_requests",
25
+ /** 单请求详情(响应体/头/时序;1.7.0 原生) */
26
+ network_get: "get_network_request",
24
27
  /**
25
- * chrome-devtools-mcp console 日志工具(上游若不暴露则 doConsole 走 evaluate 注入兜底)。
26
- * v0.5 M0.5b 暂不接入 console 工具实装(占位;M0.5c network 时统一上线)。
28
+ * chrome-devtools-mcp console 抓取工具(1.7.0 原生 list_console_messages)。
29
+ * v1.11(round1 T5):从 v0.5 M0.5b 占位变实装。
27
30
  */
28
- console_log: "console_log",
29
- /** evaluate_script(既有 doEvaluate 在 BrowseChannel.ts;此处仅记录名用于 doConsole/doNetwork 兜底) */
31
+ console_log: "list_console_messages",
32
+ /** evaluate_script(既有 doEvaluate 在 BrowseChannel.ts;此处仅记录名用于历史探测) */
30
33
  evaluate_script: "evaluate_script",
31
34
  });
35
+ /**
36
+ * Lasso network_filter → 上游 resourceTypes 映射(1.7.0 list_network_requests
37
+ * FILTERABLE_RESOURCE_TYPES:document/stylesheet/image/media/font/script/xhr/fetch/...)。
38
+ * "all" / "3rd-party" 不过滤(3rd-party 判定在 network.ts 工具层,host 精确匹配)。
39
+ */
40
+ const FILTER_TO_RESOURCE_TYPES = {
41
+ xhr: ["xhr"],
42
+ fetch: ["fetch"],
43
+ img: ["image"],
44
+ "3rd-party": undefined,
45
+ all: undefined,
46
+ };
32
47
  // ============================================================
33
48
  // doPdf:pdf action handler(parse6 §3.3.3 实装)
34
49
  // ============================================================
@@ -89,82 +104,44 @@ export async function doPdf(c, _url, opts) {
89
104
  return { preview: base64 };
90
105
  }
91
106
  // ============================================================
92
- // doNetwork:network action handler(parse6 §3.4.2 实装)
107
+ // doNetwork:network action handler(v1.11 round1 T5 原生化实装)
93
108
  // ============================================================
94
109
  /**
95
110
  * network action handler —— 经 BrowseChannel.actionDispatch Map 追加(INV-33)。
96
111
  *
97
- * 实现路径(parse6 §3.4 + §4.4 + §7.1 F2):
98
- * - v0.5 MVP evaluate_script 注入 PerformanceObserver(JS-level 抓取)
99
- * - 上游 chrome-devtools-mcp 若暴露专门 `network_log` 工具(doctor 探测),v0.6+ 切换
100
- * - JS-level 抓取的已知限制(F2):proxy / TUN 透明代理改 timing 时可能抓不全;
101
- * network.ts 工具层会在低计数时挂 data.next_step 提示(不阻断 worked outcome)
112
+ * v1.11(round1 T5):0.3.0 时代的 evaluate_script 注入 PerformanceObserver 路径
113
+ * **删除**,改调 1.7.0 原生 `list_network_requests`(CDP Network 域采集):
114
+ * - 数据完整度:method/status 全量(不再受 fake-ip TUN timing 抓不全影响——F2 关闭)
115
+ * - browse 流程 NAV_FIRST_ACTIONS 先导航 上游采「最近一次导航以来」的请求,
116
+ * navigate-first 流程 1:1 契合
102
117
  *
103
- * opts(BrowseOptions.network_*):
104
- * - network_filter : "xhr" | "fetch" | "img" | "3rd-party" | "all"(默认 "all";过滤在
105
- * network.ts 工具层做,doNetwork 抓全量让工具层决定)
106
- * - network_include_bodies : boolean(v0.5 不实装;schema forward-compat)
107
- * - network_timeout_ms : number(默认 3000ms;PerformanceObserver 采集窗口)
118
+ * 上游响应(1.7.0 McpResponse 文本渲染,NetworkFormatter concise 格式):
119
+ * - `## Network requests` + 分页信息行 + 每请求一行
120
+ * `reqid=<N> <METHOD> <url> [<status>]`(可能带 ` [selected ...]` 后缀)
121
+ * - 按行正则抽取(upstream-response.ts 围栏提取同范式)。
108
122
  *
109
- * 注入脚本(与 parse6 §3.4.2 伪码逐行对齐):
110
- * - new PerformanceObserver((list) => { for (e of list.getEntries()) entries.push({
111
- * name: e.name, type: e.initiatorType, duration: e.duration,
112
- * ttfb: e.responseStart - e.requestStart, bytes: e.transferSize,
113
- * workerStart: e.workerStart
114
- * }) })
115
- * - obs.observe({ type: "resource", buffered: true }) // buffered=true 拉历史 + 后续
116
- * - setTimeout(() => { obs.disconnect(); resolve(JSON.stringify(entries)); }, timeout_ms)
123
+ * opts(BrowseOptions.network_*):
124
+ * - network_filter : "xhr"|"fetch"|"img"|"3rd-party"|"all" 映射上游 resourceTypes
125
+ * (xhr→xhr / fetch→fetch / img→image;3rd-party/all 全量,
126
+ * 3rd-party 判定在 network.ts 工具层)
127
+ * - network_timeout_ms / network_include_bodies:不再适用(原生工具即时返回);
128
+ * 字段保留(zod 契约稳定),值被忽略
117
129
  *
118
- * @returns Partial<BrowseResult>:preview 字段含 entries JSON 字符串
119
- * (network.ts 工具层会把它过 applyOutputEnvelope;INV-34 同源)
130
+ * @returns Partial<BrowseResult>:preview = entries JSON 字符串(network.ts 工具层
131
+ * filterResources + applyOutputEnvelope;INV-34 同源)
120
132
  */
121
133
  export async function doNetwork(c, _url, opts) {
122
- // PerformanceObserver 采集窗口(默认 3000ms;上限 30000ms caller 误传巨大值)
123
- const timeoutMs = Math.max(100, Math.min(opts.network_timeout_ms ?? 3000, 30_000));
124
- // 注入表达式(与 parse6 §3.4.2 伪码逐行对齐)
125
- // 注:JSON.stringify entries 数组在 page 端完成;CDP 透传 text 回来
126
- // W1-DEF-1(v1.8):函数表达式(上游 0.3.0 evaluate_script 契约,上游会 await
127
- // 返回的 Promise),不再传 IIFE 语句串。
128
- const expr = `() => {
129
- return new Promise((resolve) => {
130
- var entries = [];
131
- if (typeof PerformanceObserver === "undefined") {
132
- resolve("[]");
133
- return;
134
- }
135
- try {
136
- var obs = new PerformanceObserver(function(list) {
137
- list.getEntries().forEach(function(e) {
138
- entries.push({
139
- name: e.name,
140
- type: e.initiatorType,
141
- duration: e.duration,
142
- ttfb: e.responseStart - e.requestStart,
143
- bytes: e.transferSize,
144
- workerStart: e.workerStart
145
- });
146
- });
147
- });
148
- obs.observe({ type: "resource", buffered: true });
149
- setTimeout(function() {
150
- try { obs.disconnect(); } catch (_) {}
151
- resolve(JSON.stringify(entries));
152
- }, ${timeoutMs});
153
- } catch (e) {
154
- resolve("[]");
155
- }
156
- });
157
- }`;
134
+ // filter 上游 resourceTypes(undefined = 全量)
135
+ const filter = opts.network_filter ?? "all";
136
+ const resourceTypes = FILTER_TO_RESOURCE_TYPES[filter];
158
137
  let r;
159
138
  try {
160
- r = (await c.callTool(CDP_UPSTREAM_TOOL_NAMES.evaluate_script, {
161
- function: expr,
139
+ r = (await c.callTool(CDP_UPSTREAM_TOOL_NAMES.network_log, {
140
+ ...(resourceTypes ? { resourceTypes } : {}),
162
141
  }));
163
142
  }
164
143
  catch (e) {
165
- // evaluate_script 调用失败(chrome-devtools-mcp 上游协议错 / 子进程挂)
166
- // → 标准化为 upstream_network_error 前缀;上层 network.ts 检测后包成
167
- // outcome=didnt + retrieval_method=upstream_unsupported:network(守 F2)
144
+ // 上游工具缺失/协议错 标准化 upstream_network_error 前缀(network.ts Go/No-Go F2 识别)
168
145
  const msg = String(e).slice(0, 200);
169
146
  throw new Error(`upstream_network_error:tool_call_failed:${msg}`);
170
147
  }
@@ -172,39 +149,83 @@ export async function doNetwork(c, _url, opts) {
172
149
  const detail = firstText(r) ?? "unknown";
173
150
  throw new Error(`upstream_network_error:is_error:${detail}`);
174
151
  }
175
- // entries JSON 作为 preview 返回;network.ts 工具层会做 3rd-party 标记 + 过滤 + envelope
176
- // W1-DEF-1b(v1.8):经 parseEvalResult 解围栏(脚本 return JSON.stringify(entries));
177
- // 无围栏/解析失败兜底 "[]"(空 entries 是合法结果,上层 JSON.parse 不炸)
178
- const v = parseEvalResult(r);
179
- const text = v == null ? "[]" : typeof v === "string" ? v : JSON.stringify(v);
180
- return { preview: text };
152
+ // 逐行抽 reqid=<N> <METHOD> <url> [<status>]
153
+ // entry.type 回填 filter canonical initiatorType(工具层 filterResources 直通;
154
+ // 上游 resourceTypes 已过滤,回填保证 e.type 断言不被清空)
155
+ const canonicalType = filter === "xhr" ? "xmlhttprequest" : filter === "img" ? "img" : filter;
156
+ const text = firstText(r) ?? "";
157
+ const entries = parseNetworkRequestLines(text).map((e) => ({
158
+ ...e,
159
+ ...(filter === "all" || filter === "3rd-party" ? {} : { type: canonicalType }),
160
+ }));
161
+ return { preview: JSON.stringify(entries) };
162
+ }
163
+ /** 1.7.0 list_network_requests 文本行 → 结构化条目(围栏提取范式)。 */
164
+ export function parseNetworkRequestLines(text) {
165
+ const out = [];
166
+ for (const line of text.split("\n")) {
167
+ // reqid=123 GET https://example.com/ [200](status 可能非数字:pending / failed)
168
+ const m = line.match(/^reqid=(-?\d+)\s+(\S+)\s+(\S+)\s+\[([^\]]*)\]/);
169
+ if (!m)
170
+ continue;
171
+ out.push({
172
+ name: m[3],
173
+ type: "",
174
+ reqid: parseInt(m[1], 10),
175
+ method: m[2],
176
+ status: m[4],
177
+ });
178
+ }
179
+ return out;
181
180
  }
182
181
  // ============================================================
183
- // doConsole:console action handler(v0.5 M0.5b 占位,M0.5c 接入)
182
+ // doConsole:console action handler(v1.11 round1 T5 实装,原 v0.5 占位废除)
184
183
  // ============================================================
185
184
  /**
186
185
  * console action handler —— 经 BrowseChannel.actionDispatch Map 追加(INV-33)。
187
186
  *
188
- * v0.5 M0.5b 立场:占位实装 —— parse6 §2.1 把 console entry 加入 dispatch Map(INV-33
189
- * 要求三 action 必在 Map),但 M0.5b 阶段不实装真正 console 日志抓取(推 M0.5c network
190
- * 时统一上线 evaluate_script 注入范式 + 3rd-party 过滤等)。
187
+ * v1.11(round1 T5):从占位("v0.5 M0.5b placeholder")变实装——调 1.7.0 原生
188
+ * `list_console_messages`。
191
189
  *
192
- * R-CI-02:不在本函数返回特殊形状;与既有 doEvaluate 同档 throw(无 js 时 throw)
193
- * BrowseChannel.browse() classifyBrowseError outcome=unknown
194
- * 上层(暂无 console.ts 工具)未来 console.ts 工具会包装成 outcome=didnt
195
- * + retrieval_method=console_not_implemented_in_v0.5 + next_step。
190
+ * 上游响应(ConsoleFormatter concise 格式):
191
+ * - `## Console messages` + 每消息一行
192
+ * `msgid=<N> [<type>] <text> (<N> args)`(可能带 ` [N times]` 后缀)
196
193
  *
197
- * 设计:本占位**永不抛错**(return + preview 而非 throw),让 BrowseChannel.browse()
198
- * outcome=worked + retrieval_method=chrome_devtools_mcp_console_placeholder。
199
- * 这样 INV-33 断言("console" 必须在 dispatch Map)落地,且不影响任何现有调用路径
200
- * (v0.5 没有 console tool 注册;只是 Map entry 预留)。
194
+ * @returns Partial<BrowseResult>:preview = messages JSON 字符串
201
195
  */
202
- export async function doConsole(_c, _url, _opts) {
203
- // v0.5 M0.5b 占位:返 preview 标识 + retrieval_method 暗示未实装
204
- // M0.5c network 时会改为真正的 evaluate_script 注入 + console entries 解析
205
- return {
206
- preview: "console action: v0.5 M0.5b placeholder (M0.5c will implement evaluate_script injection)",
207
- };
196
+ export async function doConsole(c, _url, _opts) {
197
+ let r;
198
+ try {
199
+ r = (await c.callTool(CDP_UPSTREAM_TOOL_NAMES.console_log, {}));
200
+ }
201
+ catch (e) {
202
+ const msg = String(e).slice(0, 200);
203
+ throw new Error(`upstream_console_error:tool_call_failed:${msg}`);
204
+ }
205
+ if (r.isError) {
206
+ const detail = firstText(r) ?? "unknown";
207
+ throw new Error(`upstream_console_error:is_error:${detail}`);
208
+ }
209
+ const messages = parseConsoleMessageLines(firstText(r) ?? "");
210
+ return { preview: JSON.stringify(messages) };
211
+ }
212
+ /** 1.7.0 list_console_messages 文本行 → 结构化消息。 */
213
+ export function parseConsoleMessageLines(text) {
214
+ const out = [];
215
+ for (const line of text.split("\n")) {
216
+ // msgid=1 [log] hello world (2 args) [3 times]
217
+ const m = line.match(/^msgid=(-?\d+)\s+\[([^\]]+)\]\s+(.*)\s+\((\d+)\s+args?\)(?:\s+\[(\d+) times\])?$/);
218
+ if (!m)
219
+ continue;
220
+ out.push({
221
+ id: parseInt(m[1], 10),
222
+ type: m[2],
223
+ text: m[3],
224
+ argsCount: parseInt(m[4], 10),
225
+ ...(m[5] ? { count: parseInt(m[5], 10) } : {}),
226
+ });
227
+ }
228
+ return out;
208
229
  }
209
230
  // ============================================================
210
231
  // helper:firstText(与 BrowseChannel.ts 同构)