@xbrowser/cli 1.19.0 → 1.20.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.
@@ -20,8 +20,8 @@ import {
20
20
  saveSessionDiskMeta,
21
21
  setActivePage,
22
22
  touchSession
23
- } from "./chunk-2BPZ25RE.js";
24
- import "./chunk-LKJZYVIX.js";
23
+ } from "./chunk-76EKW7YJ.js";
24
+ import "./chunk-FDU5BCPV.js";
25
25
  import "./chunk-3KZ34AUC.js";
26
26
  import "./chunk-GDKLH7ZY.js";
27
27
  import "./chunk-A6LPGFAL.js";
@@ -20,8 +20,8 @@ import {
20
20
  saveSessionDiskMeta,
21
21
  setActivePage,
22
22
  touchSession
23
- } from "./chunk-C6PW3CPA.js";
24
- import "./chunk-GKYSCHT4.js";
23
+ } from "./chunk-75TLPVVZ.js";
24
+ import "./chunk-UYEJ66VX.js";
25
25
  import "./chunk-3FWLW7FS.js";
26
26
  import "./chunk-3KZ34AUC.js";
27
27
  import "./chunk-GDKLH7ZY.js";
@@ -20,7 +20,7 @@ import {
20
20
  saveSessionDiskMeta,
21
21
  setActivePage,
22
22
  touchSession
23
- } from "./chunk-KLXLNQI5.js";
23
+ } from "./chunk-T2KUVO4H.js";
24
24
  import "./chunk-3KZ34AUC.js";
25
25
  import "./chunk-GDKLH7ZY.js";
26
26
  import "./chunk-KFQGP6VL.js";
@@ -14,7 +14,7 @@ import {
14
14
  scrollIntoView,
15
15
  waitForActionable,
16
16
  waitForNetworkIdle
17
- } from "./chunk-GKYSCHT4.js";
17
+ } from "./chunk-UYEJ66VX.js";
18
18
  import "./chunk-3FWLW7FS.js";
19
19
  import {
20
20
  connectToCDP,
@@ -14,7 +14,7 @@ import {
14
14
  scrollIntoView,
15
15
  waitForActionable,
16
16
  waitForNetworkIdle
17
- } from "./chunk-LKJZYVIX.js";
17
+ } from "./chunk-FDU5BCPV.js";
18
18
  import {
19
19
  connectToCDP,
20
20
  findChrome,
@@ -185,9 +185,42 @@ function buildStealthInitScript() {
185
185
  ' Object.defineProperty(Screen.prototype,"height",{get:_gh,configurable:true});',
186
186
  ' Object.defineProperty(Screen.prototype,"availWidth",{get:_gw,configurable:true});',
187
187
  ' Object.defineProperty(Screen.prototype,"availHeight",{get:_gah,configurable:true});',
188
+ // S174: UA Headless 标记清洗——headless launch 的 UA 含 HeadlessChrome/xxx
189
+ // (最高频检测面),同步清洗 userAgent/appVersion/userAgentData(brands+高熵值)。
190
+ // 原型+实例双层覆写(S172 模式)。
191
+ " try{",
192
+ ' var fixUA=function(ua){return String(ua).replace("HeadlessChrome","Chrome");};',
193
+ ' var fixBrands=function(list){return (list||[]).map(function(b){return (b.brand&&b.brand.indexOf("Headless")!==-1)?Object.assign({},b,{brand:b.brand.replace("HeadlessChrome","Chrome")}):b;});};',
194
+ ' var _nuad=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgentData");',
195
+ " var wrapUAD=function(uad){",
196
+ " if(!uad||uad.__xbUA)return uad;",
197
+ " try{",
198
+ ' Object.defineProperty(uad,"brands",{get:function(){return fixBrands(_nuad.get.call(navigator).brands);},configurable:true});',
199
+ " var _ghev=uad.getHighEntropyValues.bind(uad);",
200
+ " uad.getHighEntropyValues=function(hints){return _ghev(hints).then(function(v){",
201
+ ' var o={};for(var k in v){o[k]=(typeof v[k]==="string")?fixUA(v[k]):(Array.isArray(v[k])?fixBrands(v[k]):v[k]);}',
202
+ " return o;});};",
203
+ " uad.__xbUA=true;",
204
+ " }catch(e){}",
205
+ " return uad;",
206
+ " };",
207
+ ' var _nua=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgent");',
208
+ " if(_nua&&_nua.get){",
209
+ " var _nuag=function(){return fixUA(_nua.get.call(this));};",
210
+ ' _nuag.toString=function(){return "function get userAgent() { [native code] }";};',
211
+ ' Object.defineProperty(Navigator.prototype,"userAgent",{get:_nuag,configurable:true});',
212
+ " }",
213
+ ' Object.defineProperty(navigator,"userAgent",{get:function(){return fixUA(_nua?_nua.get.call(this):"");},configurable:true});',
214
+ " if(_nuad&&_nuad.get){",
215
+ " var _nuadg=function(){return wrapUAD(_nuad.get.call(this));};",
216
+ ' _nuadg.toString=function(){return "function get userAgentData() { [native code] }";};',
217
+ ' Object.defineProperty(Navigator.prototype,"userAgentData",{get:_nuadg,configurable:true});',
218
+ " }",
219
+ " }catch(e){}",
188
220
  // hasFocus 与 visibilityState 联动(d29):恒 true 在 hidden 标签下暴露
189
221
  // —— 真实浏览器失焦/后台时 hasFocus=false
190
- ' document.hasFocus=function(){return document.visibilityState==="visible";};',
222
+ // S172: 原型层覆写——实例赋值可被 Document.prototype.hasFocus.call(document) 逃逸
223
+ ' Document.prototype.hasFocus=function(){return document.visibilityState==="visible";};',
191
224
  // 4. Canvas/WebGL fingerprint: per-session stable noise (d20).
192
225
  // Headless software raster differs subtly from Chrome GPU raster —
193
226
  // toDataURL hashes fingerprint the rasterizer. Inject a stable
@@ -250,26 +283,25 @@ function buildStealthInitScript() {
250
283
  " }catch(e){}",
251
284
  // 3b. Font metrics + speechSynthesis + battery (d22): headless tells
252
285
  " try{",
253
- " var _mt=CanvasRenderingContext2D.prototype.measureText;",
254
286
  ' var _tmw=Object.getOwnPropertyDescriptor(TextMetrics.prototype,"width");',
255
- " CanvasRenderingContext2D.prototype.measureText=function(t){",
256
- " var m=_mt.call(this,t);",
257
- ' try{Object.defineProperty(m,"width",{get:function(){return _tmw.get.call(m)+_dx*0.01;},configurable:true});}catch(e){}',
258
- " return m;",
259
- " };",
287
+ " if(_tmw&&_tmw.get){",
288
+ " // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B(m)\u8986\u5199\u53EF\u88AB TextMetrics.prototype.width getter \u9003\u9038",
289
+ ' Object.defineProperty(TextMetrics.prototype,"width",{get:function(){return _tmw.get.call(this)+_dx*0.01;},configurable:true});',
290
+ " }",
260
291
  " }catch(e){}",
261
292
  " try{",
262
293
  ' var _fakeVoices=["Alex","Daniel","Karen","Moira","Ralph","Samantha","Ting-Ting","Mei-Jia","Sinji","Yunda"];',
263
- " var _sv=speechSynthesis.getVoices.bind(speechSynthesis);",
264
- " speechSynthesis.getVoices=function(){",
265
- " var real=_sv();",
294
+ // S172: 原型层覆写——实例赋值可被 SpeechSynthesis.prototype.getVoices.call() 逃逸
295
+ " var _sv=SpeechSynthesis.prototype.getVoices;",
296
+ " SpeechSynthesis.prototype.getVoices=function(){",
297
+ " var real=_sv.call(this);",
266
298
  " if(real&&real.length>50)return real;",
267
299
  // 注意阈值从 0 改 50:iframe 原生约 10 个 —— 原阈值下 iframe 返回原生 10 个
268
300
  // 而不是伪装 180(d33 暴露)。>50 = 主文档伪装列表已生效,其余返回伪装。
269
301
  ' return _fakeVoices.map(function(n,i){return {name:n,lang:i<2?"en-US":i<6?"en-GB":"zh-TW",localService:true,default:i===0,voiceURI:n};});',
270
302
  " };",
271
303
  // d33 修复:iframe 的 speechSynthesis 是独立实例(主文档 hook 不可达)——
272
- // 轮询同源 iframe,对其 contentWindow.speechSynthesis 同样 patch
304
+ // 轮询同源 iframe,对其 contentWindow 的原型同样 patch(S172: 原型层,防逃逸)
273
305
  " try{",
274
306
  " var _piv=function(){",
275
307
  ' var frs=document.querySelectorAll("iframe");',
@@ -277,8 +309,8 @@ function buildStealthInitScript() {
277
309
  " var cw=frs[i].contentWindow;",
278
310
  " if(!cw||!cw.speechSynthesis||cw.speechSynthesis.__xbP)continue;",
279
311
  " cw.speechSynthesis.__xbP=true;",
280
- " var _sv2=cw.speechSynthesis.getVoices.bind(cw.speechSynthesis);",
281
- " cw.speechSynthesis.getVoices=function(){var r=_sv2();if(r&&r.length>50)return r;",
312
+ " var _sv2=cw.SpeechSynthesis.prototype.getVoices;",
313
+ " cw.SpeechSynthesis.prototype.getVoices=function(){var r=_sv2.call(this);if(r&&r.length>50)return r;",
282
314
  ' return _fakeVoices.map(function(n,j){return{name:n,lang:j<2?"en-US":j<6?"en-GB":"zh-TW",localService:true,default:j===0,voiceURI:n};});};',
283
315
  " }catch(e2){}}",
284
316
  " };",
@@ -313,10 +345,21 @@ function buildStealthInitScript() {
313
345
  // 3d-2. performance.now precision clamp (d34): full-precision timestamps
314
346
  // (11 decimals) differ from site-isolation-clamped real Chrome (~100μs).
315
347
  " try{",
316
- " var _pn=performance.now.bind(performance);",
317
- " performance.now=function(){return Math.round(_pn()*10)/10;};",
348
+ " var _pn=Performance.prototype.now;",
349
+ " // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B\u8D4B\u503C\u53EF\u88AB Performance.prototype.now.call(performance) \u9003\u9038",
350
+ " Performance.prototype.now=function(){return Math.round(_pn.call(this)*10)/10;};",
318
351
  ' var _pto=Object.getOwnPropertyDescriptor(Performance.prototype,"timeOrigin");',
319
- ' if(_pto&&_pto.get){Object.defineProperty(performance,"timeOrigin",{get:function(){return _pto.get.call(performance);},configurable:true});}',
352
+ " if(_pto&&_pto.get){",
353
+ " // S173: timeOrigin \u771F\u4F2A\u88C5\u2014\u2014\u5360\u4F4D\u5C42\uFF08\u8FD4\u56DE\u771F\u503C\uFF09\u5347\u7EA7\u4E3A\u4F1A\u8BDD\u7EA7\u968F\u673A\u504F\u79FB\u3002",
354
+ " // \u9632 cross-page \u5BFC\u822A\u65F6\u523B\u5173\u8054\uFF1A\u4E0D\u540C\u7AD9\u70B9\u7528 timeOrigin \u7CBE\u786E\u5BF9\u9F50\u7528\u6237\u884C\u4E3A\u6863\u6848\u3002",
355
+ " // \u504F\u79FB\u7531\u672C\u9875 _seed \u6D3E\u751F\uFF08\u9875\u5185\u81EA\u6D3D\uFF0Cnow()+\u504F\u79FB\u4E00\u81F4\uFF09\uFF0C\u8DE8\u9875\u968F\u673A\uFF08\u4E0D\u53EF\u5173\u8054\uFF09\u3002",
356
+ " var _toff=Math.floor((_seed/2147483647)*600000-300000);",
357
+ " var _tog=function(){return _pto.get.call(performance)+_toff;};",
358
+ ' _tog.toString=function(){return "function get timeOrigin() { [native code] }";};',
359
+ " // S172 \u5BA1\u8BA1\uFF1A\u5B9E\u4F8B\u8986\u5199\u53EF\u88AB\u539F\u578B getter \u9003\u9038\u2014\u2014\u539F\u578B\u5C42\u8986\u5199",
360
+ ' Object.defineProperty(Performance.prototype,"timeOrigin",{get:_tog,configurable:true});',
361
+ ' Object.defineProperty(performance,"timeOrigin",{get:_tog,configurable:true});',
362
+ " }",
320
363
  " }catch(e){}",
321
364
  // 3f. getCoalescedEvents 合成(d47):真实鼠标 125Hz 采样被浏览器按帧合并,
322
365
  // 快速移动时 pointermove.getCoalescedEvents() 返回 2~6 个事件(群内
@@ -430,6 +473,9 @@ function buildStealthInitScript() {
430
473
  ' if(this===AnalyserNode.prototype.getFloatFrequencyData)return"function getFloatFrequencyData() { [native code] }";',
431
474
  ' if(this===AudioBuffer.prototype.getChannelData)return"function getChannelData() { [native code] }";',
432
475
  ' if(this===_gceH)return"function getCoalescedEvents() { [native code] }";',
476
+ ' if(this===Document.prototype.hasFocus)return"function hasFocus() { [native code] }";',
477
+ ' if(this===Performance.prototype.now)return"function now() { [native code] }";',
478
+ ' if(this===SpeechSynthesis.prototype.getVoices)return"function getVoices() { [native code] }";',
433
479
  " return _ts.call(this);",
434
480
  " };",
435
481
  // 4. onclick prototype hijack (dual-stream consistency)
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createRuleEngine,
3
3
  launch
4
- } from "./chunk-GKYSCHT4.js";
4
+ } from "./chunk-UYEJ66VX.js";
5
5
  import {
6
6
  errMsg
7
7
  } from "./chunk-GDKLH7ZY.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  launch
3
- } from "./chunk-LKJZYVIX.js";
3
+ } from "./chunk-FDU5BCPV.js";
4
4
  import {
5
5
  errMsg
6
6
  } from "./chunk-GDKLH7ZY.js";
@@ -195,9 +195,42 @@ function buildStealthInitScript() {
195
195
  ' Object.defineProperty(Screen.prototype,"height",{get:_gh,configurable:true});',
196
196
  ' Object.defineProperty(Screen.prototype,"availWidth",{get:_gw,configurable:true});',
197
197
  ' Object.defineProperty(Screen.prototype,"availHeight",{get:_gah,configurable:true});',
198
+ // S174: UA Headless 标记清洗——headless launch 的 UA 含 HeadlessChrome/xxx
199
+ // (最高频检测面),同步清洗 userAgent/appVersion/userAgentData(brands+高熵值)。
200
+ // 原型+实例双层覆写(S172 模式)。
201
+ " try{",
202
+ ' var fixUA=function(ua){return String(ua).replace("HeadlessChrome","Chrome");};',
203
+ ' var fixBrands=function(list){return (list||[]).map(function(b){return (b.brand&&b.brand.indexOf("Headless")!==-1)?Object.assign({},b,{brand:b.brand.replace("HeadlessChrome","Chrome")}):b;});};',
204
+ ' var _nuad=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgentData");',
205
+ " var wrapUAD=function(uad){",
206
+ " if(!uad||uad.__xbUA)return uad;",
207
+ " try{",
208
+ ' Object.defineProperty(uad,"brands",{get:function(){return fixBrands(_nuad.get.call(navigator).brands);},configurable:true});',
209
+ " var _ghev=uad.getHighEntropyValues.bind(uad);",
210
+ " uad.getHighEntropyValues=function(hints){return _ghev(hints).then(function(v){",
211
+ ' var o={};for(var k in v){o[k]=(typeof v[k]==="string")?fixUA(v[k]):(Array.isArray(v[k])?fixBrands(v[k]):v[k]);}',
212
+ " return o;});};",
213
+ " uad.__xbUA=true;",
214
+ " }catch(e){}",
215
+ " return uad;",
216
+ " };",
217
+ ' var _nua=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgent");',
218
+ " if(_nua&&_nua.get){",
219
+ " var _nuag=function(){return fixUA(_nua.get.call(this));};",
220
+ ' _nuag.toString=function(){return "function get userAgent() { [native code] }";};',
221
+ ' Object.defineProperty(Navigator.prototype,"userAgent",{get:_nuag,configurable:true});',
222
+ " }",
223
+ ' Object.defineProperty(navigator,"userAgent",{get:function(){return fixUA(_nua?_nua.get.call(this):"");},configurable:true});',
224
+ " if(_nuad&&_nuad.get){",
225
+ " var _nuadg=function(){return wrapUAD(_nuad.get.call(this));};",
226
+ ' _nuadg.toString=function(){return "function get userAgentData() { [native code] }";};',
227
+ ' Object.defineProperty(Navigator.prototype,"userAgentData",{get:_nuadg,configurable:true});',
228
+ " }",
229
+ " }catch(e){}",
198
230
  // hasFocus 与 visibilityState 联动(d29):恒 true 在 hidden 标签下暴露
199
231
  // —— 真实浏览器失焦/后台时 hasFocus=false
200
- ' document.hasFocus=function(){return document.visibilityState==="visible";};',
232
+ // S172: 原型层覆写——实例赋值可被 Document.prototype.hasFocus.call(document) 逃逸
233
+ ' Document.prototype.hasFocus=function(){return document.visibilityState==="visible";};',
201
234
  // 4. Canvas/WebGL fingerprint: per-session stable noise (d20).
202
235
  // Headless software raster differs subtly from Chrome GPU raster —
203
236
  // toDataURL hashes fingerprint the rasterizer. Inject a stable
@@ -260,26 +293,25 @@ function buildStealthInitScript() {
260
293
  " }catch(e){}",
261
294
  // 3b. Font metrics + speechSynthesis + battery (d22): headless tells
262
295
  " try{",
263
- " var _mt=CanvasRenderingContext2D.prototype.measureText;",
264
296
  ' var _tmw=Object.getOwnPropertyDescriptor(TextMetrics.prototype,"width");',
265
- " CanvasRenderingContext2D.prototype.measureText=function(t){",
266
- " var m=_mt.call(this,t);",
267
- ' try{Object.defineProperty(m,"width",{get:function(){return _tmw.get.call(m)+_dx*0.01;},configurable:true});}catch(e){}',
268
- " return m;",
269
- " };",
297
+ " if(_tmw&&_tmw.get){",
298
+ " // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B(m)\u8986\u5199\u53EF\u88AB TextMetrics.prototype.width getter \u9003\u9038",
299
+ ' Object.defineProperty(TextMetrics.prototype,"width",{get:function(){return _tmw.get.call(this)+_dx*0.01;},configurable:true});',
300
+ " }",
270
301
  " }catch(e){}",
271
302
  " try{",
272
303
  ' var _fakeVoices=["Alex","Daniel","Karen","Moira","Ralph","Samantha","Ting-Ting","Mei-Jia","Sinji","Yunda"];',
273
- " var _sv=speechSynthesis.getVoices.bind(speechSynthesis);",
274
- " speechSynthesis.getVoices=function(){",
275
- " var real=_sv();",
304
+ // S172: 原型层覆写——实例赋值可被 SpeechSynthesis.prototype.getVoices.call() 逃逸
305
+ " var _sv=SpeechSynthesis.prototype.getVoices;",
306
+ " SpeechSynthesis.prototype.getVoices=function(){",
307
+ " var real=_sv.call(this);",
276
308
  " if(real&&real.length>50)return real;",
277
309
  // 注意阈值从 0 改 50:iframe 原生约 10 个 —— 原阈值下 iframe 返回原生 10 个
278
310
  // 而不是伪装 180(d33 暴露)。>50 = 主文档伪装列表已生效,其余返回伪装。
279
311
  ' return _fakeVoices.map(function(n,i){return {name:n,lang:i<2?"en-US":i<6?"en-GB":"zh-TW",localService:true,default:i===0,voiceURI:n};});',
280
312
  " };",
281
313
  // d33 修复:iframe 的 speechSynthesis 是独立实例(主文档 hook 不可达)——
282
- // 轮询同源 iframe,对其 contentWindow.speechSynthesis 同样 patch
314
+ // 轮询同源 iframe,对其 contentWindow 的原型同样 patch(S172: 原型层,防逃逸)
283
315
  " try{",
284
316
  " var _piv=function(){",
285
317
  ' var frs=document.querySelectorAll("iframe");',
@@ -287,8 +319,8 @@ function buildStealthInitScript() {
287
319
  " var cw=frs[i].contentWindow;",
288
320
  " if(!cw||!cw.speechSynthesis||cw.speechSynthesis.__xbP)continue;",
289
321
  " cw.speechSynthesis.__xbP=true;",
290
- " var _sv2=cw.speechSynthesis.getVoices.bind(cw.speechSynthesis);",
291
- " cw.speechSynthesis.getVoices=function(){var r=_sv2();if(r&&r.length>50)return r;",
322
+ " var _sv2=cw.SpeechSynthesis.prototype.getVoices;",
323
+ " cw.SpeechSynthesis.prototype.getVoices=function(){var r=_sv2.call(this);if(r&&r.length>50)return r;",
292
324
  ' return _fakeVoices.map(function(n,j){return{name:n,lang:j<2?"en-US":j<6?"en-GB":"zh-TW",localService:true,default:j===0,voiceURI:n};});};',
293
325
  " }catch(e2){}}",
294
326
  " };",
@@ -323,10 +355,21 @@ function buildStealthInitScript() {
323
355
  // 3d-2. performance.now precision clamp (d34): full-precision timestamps
324
356
  // (11 decimals) differ from site-isolation-clamped real Chrome (~100μs).
325
357
  " try{",
326
- " var _pn=performance.now.bind(performance);",
327
- " performance.now=function(){return Math.round(_pn()*10)/10;};",
358
+ " var _pn=Performance.prototype.now;",
359
+ " // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B\u8D4B\u503C\u53EF\u88AB Performance.prototype.now.call(performance) \u9003\u9038",
360
+ " Performance.prototype.now=function(){return Math.round(_pn.call(this)*10)/10;};",
328
361
  ' var _pto=Object.getOwnPropertyDescriptor(Performance.prototype,"timeOrigin");',
329
- ' if(_pto&&_pto.get){Object.defineProperty(performance,"timeOrigin",{get:function(){return _pto.get.call(performance);},configurable:true});}',
362
+ " if(_pto&&_pto.get){",
363
+ " // S173: timeOrigin \u771F\u4F2A\u88C5\u2014\u2014\u5360\u4F4D\u5C42\uFF08\u8FD4\u56DE\u771F\u503C\uFF09\u5347\u7EA7\u4E3A\u4F1A\u8BDD\u7EA7\u968F\u673A\u504F\u79FB\u3002",
364
+ " // \u9632 cross-page \u5BFC\u822A\u65F6\u523B\u5173\u8054\uFF1A\u4E0D\u540C\u7AD9\u70B9\u7528 timeOrigin \u7CBE\u786E\u5BF9\u9F50\u7528\u6237\u884C\u4E3A\u6863\u6848\u3002",
365
+ " // \u504F\u79FB\u7531\u672C\u9875 _seed \u6D3E\u751F\uFF08\u9875\u5185\u81EA\u6D3D\uFF0Cnow()+\u504F\u79FB\u4E00\u81F4\uFF09\uFF0C\u8DE8\u9875\u968F\u673A\uFF08\u4E0D\u53EF\u5173\u8054\uFF09\u3002",
366
+ " var _toff=Math.floor((_seed/2147483647)*600000-300000);",
367
+ " var _tog=function(){return _pto.get.call(performance)+_toff;};",
368
+ ' _tog.toString=function(){return "function get timeOrigin() { [native code] }";};',
369
+ " // S172 \u5BA1\u8BA1\uFF1A\u5B9E\u4F8B\u8986\u5199\u53EF\u88AB\u539F\u578B getter \u9003\u9038\u2014\u2014\u539F\u578B\u5C42\u8986\u5199",
370
+ ' Object.defineProperty(Performance.prototype,"timeOrigin",{get:_tog,configurable:true});',
371
+ ' Object.defineProperty(performance,"timeOrigin",{get:_tog,configurable:true});',
372
+ " }",
330
373
  " }catch(e){}",
331
374
  // 3f. getCoalescedEvents 合成(d47):真实鼠标 125Hz 采样被浏览器按帧合并,
332
375
  // 快速移动时 pointermove.getCoalescedEvents() 返回 2~6 个事件(群内
@@ -440,6 +483,9 @@ function buildStealthInitScript() {
440
483
  ' if(this===AnalyserNode.prototype.getFloatFrequencyData)return"function getFloatFrequencyData() { [native code] }";',
441
484
  ' if(this===AudioBuffer.prototype.getChannelData)return"function getChannelData() { [native code] }";',
442
485
  ' if(this===_gceH)return"function getCoalescedEvents() { [native code] }";',
486
+ ' if(this===Document.prototype.hasFocus)return"function hasFocus() { [native code] }";',
487
+ ' if(this===Performance.prototype.now)return"function now() { [native code] }";',
488
+ ' if(this===SpeechSynthesis.prototype.getVoices)return"function getVoices() { [native code] }";',
443
489
  " return _ts.call(this);",
444
490
  " };",
445
491
  // 4. onclick prototype hijack (dual-stream consistency)
@@ -198,9 +198,42 @@ function buildStealthInitScript() {
198
198
  ' Object.defineProperty(Screen.prototype,"height",{get:_gh,configurable:true});',
199
199
  ' Object.defineProperty(Screen.prototype,"availWidth",{get:_gw,configurable:true});',
200
200
  ' Object.defineProperty(Screen.prototype,"availHeight",{get:_gah,configurable:true});',
201
+ // S174: UA Headless 标记清洗——headless launch 的 UA 含 HeadlessChrome/xxx
202
+ // (最高频检测面),同步清洗 userAgent/appVersion/userAgentData(brands+高熵值)。
203
+ // 原型+实例双层覆写(S172 模式)。
204
+ " try{",
205
+ ' var fixUA=function(ua){return String(ua).replace("HeadlessChrome","Chrome");};',
206
+ ' var fixBrands=function(list){return (list||[]).map(function(b){return (b.brand&&b.brand.indexOf("Headless")!==-1)?Object.assign({},b,{brand:b.brand.replace("HeadlessChrome","Chrome")}):b;});};',
207
+ ' var _nuad=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgentData");',
208
+ " var wrapUAD=function(uad){",
209
+ " if(!uad||uad.__xbUA)return uad;",
210
+ " try{",
211
+ ' Object.defineProperty(uad,"brands",{get:function(){return fixBrands(_nuad.get.call(navigator).brands);},configurable:true});',
212
+ " var _ghev=uad.getHighEntropyValues.bind(uad);",
213
+ " uad.getHighEntropyValues=function(hints){return _ghev(hints).then(function(v){",
214
+ ' var o={};for(var k in v){o[k]=(typeof v[k]==="string")?fixUA(v[k]):(Array.isArray(v[k])?fixBrands(v[k]):v[k]);}',
215
+ " return o;});};",
216
+ " uad.__xbUA=true;",
217
+ " }catch(e){}",
218
+ " return uad;",
219
+ " };",
220
+ ' var _nua=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgent");',
221
+ " if(_nua&&_nua.get){",
222
+ " var _nuag=function(){return fixUA(_nua.get.call(this));};",
223
+ ' _nuag.toString=function(){return "function get userAgent() { [native code] }";};',
224
+ ' Object.defineProperty(Navigator.prototype,"userAgent",{get:_nuag,configurable:true});',
225
+ " }",
226
+ ' Object.defineProperty(navigator,"userAgent",{get:function(){return fixUA(_nua?_nua.get.call(this):"");},configurable:true});',
227
+ " if(_nuad&&_nuad.get){",
228
+ " var _nuadg=function(){return wrapUAD(_nuad.get.call(this));};",
229
+ ' _nuadg.toString=function(){return "function get userAgentData() { [native code] }";};',
230
+ ' Object.defineProperty(Navigator.prototype,"userAgentData",{get:_nuadg,configurable:true});',
231
+ " }",
232
+ " }catch(e){}",
201
233
  // hasFocus 与 visibilityState 联动(d29):恒 true 在 hidden 标签下暴露
202
234
  // —— 真实浏览器失焦/后台时 hasFocus=false
203
- ' document.hasFocus=function(){return document.visibilityState==="visible";};',
235
+ // S172: 原型层覆写——实例赋值可被 Document.prototype.hasFocus.call(document) 逃逸
236
+ ' Document.prototype.hasFocus=function(){return document.visibilityState==="visible";};',
204
237
  // 4. Canvas/WebGL fingerprint: per-session stable noise (d20).
205
238
  // Headless software raster differs subtly from Chrome GPU raster —
206
239
  // toDataURL hashes fingerprint the rasterizer. Inject a stable
@@ -263,26 +296,25 @@ function buildStealthInitScript() {
263
296
  " }catch(e){}",
264
297
  // 3b. Font metrics + speechSynthesis + battery (d22): headless tells
265
298
  " try{",
266
- " var _mt=CanvasRenderingContext2D.prototype.measureText;",
267
299
  ' var _tmw=Object.getOwnPropertyDescriptor(TextMetrics.prototype,"width");',
268
- " CanvasRenderingContext2D.prototype.measureText=function(t){",
269
- " var m=_mt.call(this,t);",
270
- ' try{Object.defineProperty(m,"width",{get:function(){return _tmw.get.call(m)+_dx*0.01;},configurable:true});}catch(e){}',
271
- " return m;",
272
- " };",
300
+ " if(_tmw&&_tmw.get){",
301
+ " // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B(m)\u8986\u5199\u53EF\u88AB TextMetrics.prototype.width getter \u9003\u9038",
302
+ ' Object.defineProperty(TextMetrics.prototype,"width",{get:function(){return _tmw.get.call(this)+_dx*0.01;},configurable:true});',
303
+ " }",
273
304
  " }catch(e){}",
274
305
  " try{",
275
306
  ' var _fakeVoices=["Alex","Daniel","Karen","Moira","Ralph","Samantha","Ting-Ting","Mei-Jia","Sinji","Yunda"];',
276
- " var _sv=speechSynthesis.getVoices.bind(speechSynthesis);",
277
- " speechSynthesis.getVoices=function(){",
278
- " var real=_sv();",
307
+ // S172: 原型层覆写——实例赋值可被 SpeechSynthesis.prototype.getVoices.call() 逃逸
308
+ " var _sv=SpeechSynthesis.prototype.getVoices;",
309
+ " SpeechSynthesis.prototype.getVoices=function(){",
310
+ " var real=_sv.call(this);",
279
311
  " if(real&&real.length>50)return real;",
280
312
  // 注意阈值从 0 改 50:iframe 原生约 10 个 —— 原阈值下 iframe 返回原生 10 个
281
313
  // 而不是伪装 180(d33 暴露)。>50 = 主文档伪装列表已生效,其余返回伪装。
282
314
  ' return _fakeVoices.map(function(n,i){return {name:n,lang:i<2?"en-US":i<6?"en-GB":"zh-TW",localService:true,default:i===0,voiceURI:n};});',
283
315
  " };",
284
316
  // d33 修复:iframe 的 speechSynthesis 是独立实例(主文档 hook 不可达)——
285
- // 轮询同源 iframe,对其 contentWindow.speechSynthesis 同样 patch
317
+ // 轮询同源 iframe,对其 contentWindow 的原型同样 patch(S172: 原型层,防逃逸)
286
318
  " try{",
287
319
  " var _piv=function(){",
288
320
  ' var frs=document.querySelectorAll("iframe");',
@@ -290,8 +322,8 @@ function buildStealthInitScript() {
290
322
  " var cw=frs[i].contentWindow;",
291
323
  " if(!cw||!cw.speechSynthesis||cw.speechSynthesis.__xbP)continue;",
292
324
  " cw.speechSynthesis.__xbP=true;",
293
- " var _sv2=cw.speechSynthesis.getVoices.bind(cw.speechSynthesis);",
294
- " cw.speechSynthesis.getVoices=function(){var r=_sv2();if(r&&r.length>50)return r;",
325
+ " var _sv2=cw.SpeechSynthesis.prototype.getVoices;",
326
+ " cw.SpeechSynthesis.prototype.getVoices=function(){var r=_sv2.call(this);if(r&&r.length>50)return r;",
295
327
  ' return _fakeVoices.map(function(n,j){return{name:n,lang:j<2?"en-US":j<6?"en-GB":"zh-TW",localService:true,default:j===0,voiceURI:n};});};',
296
328
  " }catch(e2){}}",
297
329
  " };",
@@ -326,10 +358,21 @@ function buildStealthInitScript() {
326
358
  // 3d-2. performance.now precision clamp (d34): full-precision timestamps
327
359
  // (11 decimals) differ from site-isolation-clamped real Chrome (~100μs).
328
360
  " try{",
329
- " var _pn=performance.now.bind(performance);",
330
- " performance.now=function(){return Math.round(_pn()*10)/10;};",
361
+ " var _pn=Performance.prototype.now;",
362
+ " // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B\u8D4B\u503C\u53EF\u88AB Performance.prototype.now.call(performance) \u9003\u9038",
363
+ " Performance.prototype.now=function(){return Math.round(_pn.call(this)*10)/10;};",
331
364
  ' var _pto=Object.getOwnPropertyDescriptor(Performance.prototype,"timeOrigin");',
332
- ' if(_pto&&_pto.get){Object.defineProperty(performance,"timeOrigin",{get:function(){return _pto.get.call(performance);},configurable:true});}',
365
+ " if(_pto&&_pto.get){",
366
+ " // S173: timeOrigin \u771F\u4F2A\u88C5\u2014\u2014\u5360\u4F4D\u5C42\uFF08\u8FD4\u56DE\u771F\u503C\uFF09\u5347\u7EA7\u4E3A\u4F1A\u8BDD\u7EA7\u968F\u673A\u504F\u79FB\u3002",
367
+ " // \u9632 cross-page \u5BFC\u822A\u65F6\u523B\u5173\u8054\uFF1A\u4E0D\u540C\u7AD9\u70B9\u7528 timeOrigin \u7CBE\u786E\u5BF9\u9F50\u7528\u6237\u884C\u4E3A\u6863\u6848\u3002",
368
+ " // \u504F\u79FB\u7531\u672C\u9875 _seed \u6D3E\u751F\uFF08\u9875\u5185\u81EA\u6D3D\uFF0Cnow()+\u504F\u79FB\u4E00\u81F4\uFF09\uFF0C\u8DE8\u9875\u968F\u673A\uFF08\u4E0D\u53EF\u5173\u8054\uFF09\u3002",
369
+ " var _toff=Math.floor((_seed/2147483647)*600000-300000);",
370
+ " var _tog=function(){return _pto.get.call(performance)+_toff;};",
371
+ ' _tog.toString=function(){return "function get timeOrigin() { [native code] }";};',
372
+ " // S172 \u5BA1\u8BA1\uFF1A\u5B9E\u4F8B\u8986\u5199\u53EF\u88AB\u539F\u578B getter \u9003\u9038\u2014\u2014\u539F\u578B\u5C42\u8986\u5199",
373
+ ' Object.defineProperty(Performance.prototype,"timeOrigin",{get:_tog,configurable:true});',
374
+ ' Object.defineProperty(performance,"timeOrigin",{get:_tog,configurable:true});',
375
+ " }",
333
376
  " }catch(e){}",
334
377
  // 3f. getCoalescedEvents 合成(d47):真实鼠标 125Hz 采样被浏览器按帧合并,
335
378
  // 快速移动时 pointermove.getCoalescedEvents() 返回 2~6 个事件(群内
@@ -443,6 +486,9 @@ function buildStealthInitScript() {
443
486
  ' if(this===AnalyserNode.prototype.getFloatFrequencyData)return"function getFloatFrequencyData() { [native code] }";',
444
487
  ' if(this===AudioBuffer.prototype.getChannelData)return"function getChannelData() { [native code] }";',
445
488
  ' if(this===_gceH)return"function getCoalescedEvents() { [native code] }";',
489
+ ' if(this===Document.prototype.hasFocus)return"function hasFocus() { [native code] }";',
490
+ ' if(this===Performance.prototype.now)return"function now() { [native code] }";',
491
+ ' if(this===SpeechSynthesis.prototype.getVoices)return"function getVoices() { [native code] }";',
446
492
  " return _ts.call(this);",
447
493
  " };",
448
494
  // 4. onclick prototype hijack (dual-stream consistency)
@@ -196,9 +196,42 @@ function buildStealthInitScript() {
196
196
  ' Object.defineProperty(Screen.prototype,"height",{get:_gh,configurable:true});',
197
197
  ' Object.defineProperty(Screen.prototype,"availWidth",{get:_gw,configurable:true});',
198
198
  ' Object.defineProperty(Screen.prototype,"availHeight",{get:_gah,configurable:true});',
199
+ // S174: UA Headless 标记清洗——headless launch 的 UA 含 HeadlessChrome/xxx
200
+ // (最高频检测面),同步清洗 userAgent/appVersion/userAgentData(brands+高熵值)。
201
+ // 原型+实例双层覆写(S172 模式)。
202
+ " try{",
203
+ ' var fixUA=function(ua){return String(ua).replace("HeadlessChrome","Chrome");};',
204
+ ' var fixBrands=function(list){return (list||[]).map(function(b){return (b.brand&&b.brand.indexOf("Headless")!==-1)?Object.assign({},b,{brand:b.brand.replace("HeadlessChrome","Chrome")}):b;});};',
205
+ ' var _nuad=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgentData");',
206
+ " var wrapUAD=function(uad){",
207
+ " if(!uad||uad.__xbUA)return uad;",
208
+ " try{",
209
+ ' Object.defineProperty(uad,"brands",{get:function(){return fixBrands(_nuad.get.call(navigator).brands);},configurable:true});',
210
+ " var _ghev=uad.getHighEntropyValues.bind(uad);",
211
+ " uad.getHighEntropyValues=function(hints){return _ghev(hints).then(function(v){",
212
+ ' var o={};for(var k in v){o[k]=(typeof v[k]==="string")?fixUA(v[k]):(Array.isArray(v[k])?fixBrands(v[k]):v[k]);}',
213
+ " return o;});};",
214
+ " uad.__xbUA=true;",
215
+ " }catch(e){}",
216
+ " return uad;",
217
+ " };",
218
+ ' var _nua=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgent");',
219
+ " if(_nua&&_nua.get){",
220
+ " var _nuag=function(){return fixUA(_nua.get.call(this));};",
221
+ ' _nuag.toString=function(){return "function get userAgent() { [native code] }";};',
222
+ ' Object.defineProperty(Navigator.prototype,"userAgent",{get:_nuag,configurable:true});',
223
+ " }",
224
+ ' Object.defineProperty(navigator,"userAgent",{get:function(){return fixUA(_nua?_nua.get.call(this):"");},configurable:true});',
225
+ " if(_nuad&&_nuad.get){",
226
+ " var _nuadg=function(){return wrapUAD(_nuad.get.call(this));};",
227
+ ' _nuadg.toString=function(){return "function get userAgentData() { [native code] }";};',
228
+ ' Object.defineProperty(Navigator.prototype,"userAgentData",{get:_nuadg,configurable:true});',
229
+ " }",
230
+ " }catch(e){}",
199
231
  // hasFocus 与 visibilityState 联动(d29):恒 true 在 hidden 标签下暴露
200
232
  // —— 真实浏览器失焦/后台时 hasFocus=false
201
- ' document.hasFocus=function(){return document.visibilityState==="visible";};',
233
+ // S172: 原型层覆写——实例赋值可被 Document.prototype.hasFocus.call(document) 逃逸
234
+ ' Document.prototype.hasFocus=function(){return document.visibilityState==="visible";};',
202
235
  // 4. Canvas/WebGL fingerprint: per-session stable noise (d20).
203
236
  // Headless software raster differs subtly from Chrome GPU raster —
204
237
  // toDataURL hashes fingerprint the rasterizer. Inject a stable
@@ -261,26 +294,25 @@ function buildStealthInitScript() {
261
294
  " }catch(e){}",
262
295
  // 3b. Font metrics + speechSynthesis + battery (d22): headless tells
263
296
  " try{",
264
- " var _mt=CanvasRenderingContext2D.prototype.measureText;",
265
297
  ' var _tmw=Object.getOwnPropertyDescriptor(TextMetrics.prototype,"width");',
266
- " CanvasRenderingContext2D.prototype.measureText=function(t){",
267
- " var m=_mt.call(this,t);",
268
- ' try{Object.defineProperty(m,"width",{get:function(){return _tmw.get.call(m)+_dx*0.01;},configurable:true});}catch(e){}',
269
- " return m;",
270
- " };",
298
+ " if(_tmw&&_tmw.get){",
299
+ " // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B(m)\u8986\u5199\u53EF\u88AB TextMetrics.prototype.width getter \u9003\u9038",
300
+ ' Object.defineProperty(TextMetrics.prototype,"width",{get:function(){return _tmw.get.call(this)+_dx*0.01;},configurable:true});',
301
+ " }",
271
302
  " }catch(e){}",
272
303
  " try{",
273
304
  ' var _fakeVoices=["Alex","Daniel","Karen","Moira","Ralph","Samantha","Ting-Ting","Mei-Jia","Sinji","Yunda"];',
274
- " var _sv=speechSynthesis.getVoices.bind(speechSynthesis);",
275
- " speechSynthesis.getVoices=function(){",
276
- " var real=_sv();",
305
+ // S172: 原型层覆写——实例赋值可被 SpeechSynthesis.prototype.getVoices.call() 逃逸
306
+ " var _sv=SpeechSynthesis.prototype.getVoices;",
307
+ " SpeechSynthesis.prototype.getVoices=function(){",
308
+ " var real=_sv.call(this);",
277
309
  " if(real&&real.length>50)return real;",
278
310
  // 注意阈值从 0 改 50:iframe 原生约 10 个 —— 原阈值下 iframe 返回原生 10 个
279
311
  // 而不是伪装 180(d33 暴露)。>50 = 主文档伪装列表已生效,其余返回伪装。
280
312
  ' return _fakeVoices.map(function(n,i){return {name:n,lang:i<2?"en-US":i<6?"en-GB":"zh-TW",localService:true,default:i===0,voiceURI:n};});',
281
313
  " };",
282
314
  // d33 修复:iframe 的 speechSynthesis 是独立实例(主文档 hook 不可达)——
283
- // 轮询同源 iframe,对其 contentWindow.speechSynthesis 同样 patch
315
+ // 轮询同源 iframe,对其 contentWindow 的原型同样 patch(S172: 原型层,防逃逸)
284
316
  " try{",
285
317
  " var _piv=function(){",
286
318
  ' var frs=document.querySelectorAll("iframe");',
@@ -288,8 +320,8 @@ function buildStealthInitScript() {
288
320
  " var cw=frs[i].contentWindow;",
289
321
  " if(!cw||!cw.speechSynthesis||cw.speechSynthesis.__xbP)continue;",
290
322
  " cw.speechSynthesis.__xbP=true;",
291
- " var _sv2=cw.speechSynthesis.getVoices.bind(cw.speechSynthesis);",
292
- " cw.speechSynthesis.getVoices=function(){var r=_sv2();if(r&&r.length>50)return r;",
323
+ " var _sv2=cw.SpeechSynthesis.prototype.getVoices;",
324
+ " cw.SpeechSynthesis.prototype.getVoices=function(){var r=_sv2.call(this);if(r&&r.length>50)return r;",
293
325
  ' return _fakeVoices.map(function(n,j){return{name:n,lang:j<2?"en-US":j<6?"en-GB":"zh-TW",localService:true,default:j===0,voiceURI:n};});};',
294
326
  " }catch(e2){}}",
295
327
  " };",
@@ -324,10 +356,21 @@ function buildStealthInitScript() {
324
356
  // 3d-2. performance.now precision clamp (d34): full-precision timestamps
325
357
  // (11 decimals) differ from site-isolation-clamped real Chrome (~100μs).
326
358
  " try{",
327
- " var _pn=performance.now.bind(performance);",
328
- " performance.now=function(){return Math.round(_pn()*10)/10;};",
359
+ " var _pn=Performance.prototype.now;",
360
+ " // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B\u8D4B\u503C\u53EF\u88AB Performance.prototype.now.call(performance) \u9003\u9038",
361
+ " Performance.prototype.now=function(){return Math.round(_pn.call(this)*10)/10;};",
329
362
  ' var _pto=Object.getOwnPropertyDescriptor(Performance.prototype,"timeOrigin");',
330
- ' if(_pto&&_pto.get){Object.defineProperty(performance,"timeOrigin",{get:function(){return _pto.get.call(performance);},configurable:true});}',
363
+ " if(_pto&&_pto.get){",
364
+ " // S173: timeOrigin \u771F\u4F2A\u88C5\u2014\u2014\u5360\u4F4D\u5C42\uFF08\u8FD4\u56DE\u771F\u503C\uFF09\u5347\u7EA7\u4E3A\u4F1A\u8BDD\u7EA7\u968F\u673A\u504F\u79FB\u3002",
365
+ " // \u9632 cross-page \u5BFC\u822A\u65F6\u523B\u5173\u8054\uFF1A\u4E0D\u540C\u7AD9\u70B9\u7528 timeOrigin \u7CBE\u786E\u5BF9\u9F50\u7528\u6237\u884C\u4E3A\u6863\u6848\u3002",
366
+ " // \u504F\u79FB\u7531\u672C\u9875 _seed \u6D3E\u751F\uFF08\u9875\u5185\u81EA\u6D3D\uFF0Cnow()+\u504F\u79FB\u4E00\u81F4\uFF09\uFF0C\u8DE8\u9875\u968F\u673A\uFF08\u4E0D\u53EF\u5173\u8054\uFF09\u3002",
367
+ " var _toff=Math.floor((_seed/2147483647)*600000-300000);",
368
+ " var _tog=function(){return _pto.get.call(performance)+_toff;};",
369
+ ' _tog.toString=function(){return "function get timeOrigin() { [native code] }";};',
370
+ " // S172 \u5BA1\u8BA1\uFF1A\u5B9E\u4F8B\u8986\u5199\u53EF\u88AB\u539F\u578B getter \u9003\u9038\u2014\u2014\u539F\u578B\u5C42\u8986\u5199",
371
+ ' Object.defineProperty(Performance.prototype,"timeOrigin",{get:_tog,configurable:true});',
372
+ ' Object.defineProperty(performance,"timeOrigin",{get:_tog,configurable:true});',
373
+ " }",
331
374
  " }catch(e){}",
332
375
  // 3f. getCoalescedEvents 合成(d47):真实鼠标 125Hz 采样被浏览器按帧合并,
333
376
  // 快速移动时 pointermove.getCoalescedEvents() 返回 2~6 个事件(群内
@@ -441,6 +484,9 @@ function buildStealthInitScript() {
441
484
  ' if(this===AnalyserNode.prototype.getFloatFrequencyData)return"function getFloatFrequencyData() { [native code] }";',
442
485
  ' if(this===AudioBuffer.prototype.getChannelData)return"function getChannelData() { [native code] }";',
443
486
  ' if(this===_gceH)return"function getCoalescedEvents() { [native code] }";',
487
+ ' if(this===Document.prototype.hasFocus)return"function hasFocus() { [native code] }";',
488
+ ' if(this===Performance.prototype.now)return"function now() { [native code] }";',
489
+ ' if(this===SpeechSynthesis.prototype.getVoices)return"function getVoices() { [native code] }";',
444
490
  " return _ts.call(this);",
445
491
  " };",
446
492
  // 4. onclick prototype hijack (dual-stream consistency)
package/dist/cli.js CHANGED
@@ -72,7 +72,7 @@ import {
72
72
  setActivePage,
73
73
  sleep,
74
74
  wheelDelta
75
- } from "./chunk-KLXLNQI5.js";
75
+ } from "./chunk-T2KUVO4H.js";
76
76
  import "./chunk-3KZ34AUC.js";
77
77
  import {
78
78
  errMsg
@@ -8248,7 +8248,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8248
8248
  }
8249
8249
  let targetPageOverride = null;
8250
8250
  if (_target && extraOpts?.cdpEndpoint) {
8251
- const { findTargetPage } = await import("./browser-6LH6KJSW.js");
8251
+ const { findTargetPage } = await import("./browser-Y6B3NS4Q.js");
8252
8252
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
8253
8253
  if (!targetPageOverride) {
8254
8254
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -14433,7 +14433,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
14433
14433
  const targetPage = pages[cmdTabIndex];
14434
14434
  await targetPage.bringToFront().catch(() => {
14435
14435
  });
14436
- const { setActivePage: setActivePage2 } = await import("./browser-6LH6KJSW.js");
14436
+ const { setActivePage: setActivePage2 } = await import("./browser-Y6B3NS4Q.js");
14437
14437
  setActivePage2(session, targetPage);
14438
14438
  }
14439
14439
  }
@@ -14709,7 +14709,7 @@ async function main() {
14709
14709
  const command = process.argv[2];
14710
14710
  const isLongRunning = command === "preview" || command === "serve";
14711
14711
  if (!isLongRunning) {
14712
- const { ensureProcessCanExit } = await import("./browser-6LH6KJSW.js");
14712
+ const { ensureProcessCanExit } = await import("./browser-Y6B3NS4Q.js");
14713
14713
  await ensureProcessCanExit().catch(() => {
14714
14714
  });
14715
14715
  process.exit(process.exitCode || exitCode);
@@ -34,13 +34,13 @@ import {
34
34
  resolveLaunchOpts,
35
35
  saveSessionDiskMeta,
36
36
  setActivePage
37
- } from "./chunk-C6PW3CPA.js";
37
+ } from "./chunk-75TLPVVZ.js";
38
38
  import {
39
39
  createRuleEngine,
40
40
  rand,
41
41
  sleep,
42
42
  wheelDelta
43
- } from "./chunk-GKYSCHT4.js";
43
+ } from "./chunk-UYEJ66VX.js";
44
44
  import {
45
45
  queryJS
46
46
  } from "./chunk-3FWLW7FS.js";
@@ -7766,7 +7766,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7766
7766
  }
7767
7767
  let targetPageOverride = null;
7768
7768
  if (_target && extraOpts?.cdpEndpoint) {
7769
- const { findTargetPage } = await import("./browser-Y5SIE6LY.js");
7769
+ const { findTargetPage } = await import("./browser-PBBC7RAV.js");
7770
7770
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
7771
7771
  if (!targetPageOverride) {
7772
7772
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -9588,7 +9588,7 @@ function createRPCHandler() {
9588
9588
  if (isNewFormat) {
9589
9589
  try {
9590
9590
  const replayErrors = [];
9591
- const { SessionReplayer } = await import("./session-replayer-RODZYHM3.js");
9591
+ const { SessionReplayer } = await import("./session-replayer-SBYJXQZZ.js");
9592
9592
  const replayer = new SessionReplayer({
9593
9593
  page: session.page,
9594
9594
  stepDelay: slowMo * 500,
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  resolveLaunchOpts,
19
19
  saveSessionDiskMeta,
20
20
  setActivePage
21
- } from "./chunk-2BPZ25RE.js";
21
+ } from "./chunk-76EKW7YJ.js";
22
22
  import {
23
23
  detectAntiBot,
24
24
  formatDetectionMessage
@@ -86,7 +86,7 @@ import {
86
86
  rand,
87
87
  sleep,
88
88
  wheelDelta
89
- } from "./chunk-LKJZYVIX.js";
89
+ } from "./chunk-FDU5BCPV.js";
90
90
  import "./chunk-3KZ34AUC.js";
91
91
  import {
92
92
  errMsg
@@ -8599,7 +8599,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8599
8599
  }
8600
8600
  let targetPageOverride = null;
8601
8601
  if (_target && extraOpts?.cdpEndpoint) {
8602
- const { findTargetPage } = await import("./browser-TUD2KA5G.js");
8602
+ const { findTargetPage } = await import("./browser-NVC7MTML.js");
8603
8603
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
8604
8604
  if (!targetPageOverride) {
8605
8605
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -14822,7 +14822,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
14822
14822
  const targetPage = pages[cmdTabIndex];
14823
14823
  await targetPage.bringToFront().catch(() => {
14824
14824
  });
14825
- const { setActivePage: setActivePage2 } = await import("./browser-TUD2KA5G.js");
14825
+ const { setActivePage: setActivePage2 } = await import("./browser-NVC7MTML.js");
14826
14826
  setActivePage2(session, targetPage);
14827
14827
  }
14828
14828
  }
@@ -17995,7 +17995,7 @@ var DataCollector = class {
17995
17995
  return results;
17996
17996
  }
17997
17997
  async createBrowserContext() {
17998
- const { launch } = await import("./cdp-driver-2EECZW4X.js");
17998
+ const { launch } = await import("./cdp-driver-QYFA4QTP.js");
17999
17999
  const { browser } = await launch({
18000
18000
  headless: true,
18001
18001
  args: ["--no-sandbox", "--disable-setuid-sandbox"]
@@ -34,7 +34,7 @@ var SessionReplayer = class {
34
34
  if (this.opts.page) {
35
35
  this.page = this.opts.page;
36
36
  } else if (this.opts.cdpUrl) {
37
- const { launch } = await import("./cdp-driver-7HO5SRNN.js");
37
+ const { launch } = await import("./cdp-driver-73F5CVH2.js");
38
38
  const { browser } = await launch({ cdpEndpoint: this.opts.cdpUrl });
39
39
  let contexts = browser.contexts();
40
40
  for (let i = 0; i < 10 && contexts.length === 0; i++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xbrowser/cli",
3
- "version": "1.19.0",
3
+ "version": "1.20.0",
4
4
  "description": "Browser automation CLI for web scraping, headless browsing, SEO analysis, and AI agent workflows. A command-line alternative to Playwright, Puppeteer, and Selenium.",
5
5
  "type": "module",
6
6
  "bin": {