@xbrowser/cli 1.21.0 → 1.23.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 (43) hide show
  1. package/README.md +21 -3
  2. package/dist/{browser-CNBSH53B.js → browser-BVRFSUXU.js} +3 -2
  3. package/dist/{browser-C2VEOJC2.js → browser-DSYUAE7H.js} +5 -4
  4. package/dist/{browser-VZOOFLAH.js → browser-Q67BJTI2.js} +4 -3
  5. package/dist/{cdp-driver-KFX4A6WR.js → cdp-driver-DC7EIUG5.js} +4 -3
  6. package/dist/{cdp-driver-7Z6ZAT5E.js → cdp-driver-T7D6H2RW.js} +335 -546
  7. package/dist/{cdp-driver-26LGCHXV.js → cdp-driver-WWO2UZDR.js} +3 -2
  8. package/dist/{chunk-Z5RTK4GW.js → chunk-2Q3GQRUP.js} +2 -2
  9. package/dist/{chunk-CLYZPSDR.js → chunk-4OU37CXP.js} +354 -576
  10. package/dist/{chunk-HWWG2ISJ.js → chunk-7OP2ISEY.js} +353 -575
  11. package/dist/{chunk-PIWNMC36.js → chunk-A3MORKYR.js} +1 -1
  12. package/dist/{chunk-3FWLW7FS.js → chunk-A7NEA4PA.js} +39 -1
  13. package/dist/{chunk-OMU63E6J.js → chunk-FBQZ3PVD.js} +5 -8
  14. package/dist/chunk-GYB5BOSP.js +602 -0
  15. package/dist/{chunk-ESJYANQO.js → chunk-IFKJO2UR.js} +360 -582
  16. package/dist/{chunk-NODRQGOK.js → chunk-IR6C24P7.js} +97 -0
  17. package/dist/{chunk-TEXCXIBW.js → chunk-LPW6QS4M.js} +5 -8
  18. package/dist/{chunk-3KZ34AUC.js → chunk-MYH6FIBZ.js} +2 -1
  19. package/dist/{chunk-AVSTNODR.js → chunk-T4WTKBWI.js} +2 -2
  20. package/dist/{chunk-HBHOKZPN.js → chunk-V6KGBU5J.js} +97 -0
  21. package/dist/{chunk-IWVG4XYZ.js → chunk-VCVDILH6.js} +2 -1
  22. package/dist/{chunk-NKW4A74J.js → chunk-XTUAUFL3.js} +5 -8
  23. package/dist/cli.js +497 -252
  24. package/dist/daemon-main.js +25 -19
  25. package/dist/{human-interaction-Y5IDH6LD.js → human-interaction-57VYIR56.js} +1 -1
  26. package/dist/{human-interaction-ZUTR5AC2.js → human-interaction-67K43B4O.js} +1 -1
  27. package/dist/{human-interaction-4YR2N6R6.js → human-interaction-MXST5ZQM.js} +1 -1
  28. package/dist/index.d.ts +52 -4
  29. package/dist/index.js +500 -256
  30. package/dist/keep-awake-M4KJS4B4.js +29 -0
  31. package/dist/{launcher-44STYRJC.js → launcher-IK2FKW6T.js} +1 -1
  32. package/dist/{launcher-EXJHHAUL.js → launcher-LUOMMGZC.js} +1 -1
  33. package/dist/{plugin-singleton-FCNDN3FX.js → plugin-singleton-GJO7EZXB.js} +1 -1
  34. package/dist/{recovery-NXC35EQN.js → recovery-6RI2FE3E.js} +1 -1
  35. package/dist/{recovery-MDWAVXE4.js → recovery-LGY25LIM.js} +1 -1
  36. package/dist/{recovery-L5GLDX4O.js → recovery-LMJW537X.js} +1 -1
  37. package/dist/{session-recorder-SLDBENVF.js → session-recorder-563ISSJK.js} +1 -1
  38. package/dist/{session-recorder-3BEVWHOK.js → session-recorder-GEZVQBKW.js} +1 -1
  39. package/dist/session-replayer-N665T3G5.js +932 -0
  40. package/dist/stealth-2AA2FSNN.js +29 -0
  41. package/dist/stealth-JOXGV34D.js +29 -0
  42. package/package.json +11 -7
  43. package/dist/session-replayer-EVD4HZBB.js +0 -413
@@ -478,6 +478,55 @@ var ACTION_SIGNAL_SCRIPT = `
478
478
  } catch(e) { /* skip */ }
479
479
  }
480
480
 
481
+ // Ordinal address (r6): ancestor form's ordinal among sibling forms + element's
482
+ // ordinal among same-tag direct children of that form. Direct children only \u2014
483
+ // nested elements have no stable single-level address.
484
+ var ordinal = null;
485
+ try {
486
+ var ordForm = el.closest ? el.closest('form') : null;
487
+ if (ordForm && el.parentElement === ordForm) {
488
+ var ordParent = ordForm.parentElement;
489
+ var formSibs = ordParent
490
+ ? Array.prototype.filter.call(ordParent.children, function(c) { return c.tagName === 'FORM'; })
491
+ : [ordForm];
492
+ var tagSibs = Array.prototype.filter.call(ordForm.children, function(c) { return c.tagName === el.tagName; });
493
+ ordinal = {
494
+ formNth: formSibs.indexOf(ordForm) + 1,
495
+ tagNth: tagSibs.indexOf(el) + 1,
496
+ };
497
+ }
498
+ } catch(e) { /* skip */ }
499
+
500
+ // Label text (r16): the <label> associated with the element (for= association or ancestor wrapper). In virtual list /
501
+ // form-row reordering scenarios, structural ordinals fail, but the label text moves in the same line as the
502
+ // control\u2014content moves, and the anchor follows the content.
503
+ var labelText = '';
504
+ try {
505
+ var lbl = null;
506
+ if (el.id) lbl = el.ownerDocument.querySelector('label[for="' + el.id + '"]');
507
+ if (!lbl && el.closest) lbl = el.closest('label');
508
+ if (lbl) labelText = (lbl.textContent || '').trim().substring(0, 40);
509
+ } catch(e) { /* skip */ }
510
+
511
+ // Element size (r25): rounded rect at record time \u2014 scoring signal for
512
+ // fingerprint disambiguation between same-fingerprint decoys.
513
+ var size = null;
514
+ try {
515
+ var szR = el.getBoundingClientRect();
516
+ if (szR.width > 0 || szR.height > 0) {
517
+ size = { w: Math.round(szR.width), h: Math.round(szR.height) };
518
+ }
519
+ } catch(e) { /* skip */ }
520
+
521
+ // Row text (r27): textContent of the closest table/list row. In virtual
522
+ // lists and sortable tables the row re-indexes \u2014 the row TEXT travels
523
+ // with the content, giving inputs a content anchor that survives reorder.
524
+ var rowText = '';
525
+ try {
526
+ var row = el.closest ? el.closest('tr,li') : null;
527
+ if (row) rowText = (row.textContent || '').trim().replace(/s+/g, ' ').substring(0, 40);
528
+ } catch(e) { /* skip */ }
529
+
481
530
  return {
482
531
  tag: tag,
483
532
  selector: selector,
@@ -491,6 +540,10 @@ var ACTION_SIGNAL_SCRIPT = `
491
540
  placeholder: el.getAttribute('placeholder') || undefined,
492
541
  ariaLabel: el.getAttribute('aria-label') || undefined,
493
542
  href: el.getAttribute('href') ? el.getAttribute('href').substring(0, 80) : undefined,
543
+ ordinal: ordinal || undefined,
544
+ labelText: labelText || undefined,
545
+ size: size || undefined,
546
+ rowText: rowText || undefined,
494
547
  };
495
548
  }
496
549
 
@@ -1128,6 +1181,50 @@ var ACTION_SIGNAL_SCRIPT = `
1128
1181
  __xb_drag_start_pos = { x: e.clientX, y: e.clientY };
1129
1182
  }, true);
1130
1183
  document.addEventListener('drop', function(e) {
1184
+ // sup-s5: OS \u6587\u4EF6\u62D6\u5165\u6355\u83B7\u2014\u2014Dropzone/Uppy \u7C7B\u4E0A\u4F20\u533A\u65E0 input[type=file]\uFF0C
1185
+ // change \u6355\u83B7\u591F\u4E0D\u7740\uFF1BdataTransfer.files \u7ECF FileReader \u5185\u8054\uFF08\u4E0E
1186
+ // filechooser \u540C\u6784\uFF09\uFF0C\u56DE\u653E\u7AEF 'drop' \u52A8\u4F5C\u7ECF dropFiles \u91CD\u653E\u3002
1187
+ try {
1188
+ var dropped = (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0)
1189
+ ? Array.prototype.slice.call(e.dataTransfer.files)
1190
+ : [];
1191
+ if (dropped.length > 0) {
1192
+ var zone = describe(resolveMeaningful(e));
1193
+ var names = dropped.map(function(f) { return f.name; });
1194
+ var readers = [];
1195
+ for (var i = 0; i < dropped.length; i++) {
1196
+ readers.push(new Promise(function(resolve) {
1197
+ var reader = new FileReader();
1198
+ reader.onload = function() { resolve(reader.result); };
1199
+ reader.onerror = function() { resolve(null); };
1200
+ reader.readAsDataURL(dropped[i]);
1201
+ }));
1202
+ }
1203
+ Promise.all(readers).then(function(contents) {
1204
+ var fileData = [];
1205
+ for (var j = 0; j < dropped.length; j++) {
1206
+ fileData.push({
1207
+ name: dropped[j].name,
1208
+ type: dropped[j].type,
1209
+ size: dropped[j].size,
1210
+ dataUrl: contents[j],
1211
+ });
1212
+ }
1213
+ pushAction('drop', {
1214
+ x: e.clientX,
1215
+ y: e.clientY,
1216
+ element: zone,
1217
+ value: names.join(', '),
1218
+ files: {
1219
+ names: names,
1220
+ count: dropped.length,
1221
+ isMultiple: dropped.length > 1,
1222
+ fileData: fileData,
1223
+ },
1224
+ });
1225
+ });
1226
+ }
1227
+ } catch(_) { /* capture must not break the drag path */ }
1131
1228
  if (__xb_drag_source && __xb_drag_start_pos) {
1132
1229
  pushAction('drag', {
1133
1230
  x: e.clientX,
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-ZTHE5RBZ.js";
4
4
 
5
5
  // src/human-interaction.ts
6
- import { execSync } from "child_process";
6
+ import { execFile } from "child_process";
7
7
 
8
8
  // src/screencast.ts
9
9
  var ScreencastCapturer = class {
@@ -278,11 +278,6 @@ var WebhookNotifier = class {
278
278
  }
279
279
  };
280
280
 
281
- // src/utils/shell-escape.ts
282
- function shellEscape(value) {
283
- return `'${value.replace(/'/g, "'\\''")}'`;
284
- }
285
-
286
281
  // src/human-interaction.ts
287
282
  var HumanInteractionManager = class {
288
283
  wsServer;
@@ -311,8 +306,10 @@ var HumanInteractionManager = class {
311
306
  tryAutoOpen(previewUrl) {
312
307
  if (!this.autoOpen) return;
313
308
  try {
314
- const cmd = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : "start";
315
- execSync(`${cmd} ${shellEscape(previewUrl)}`, { stdio: "ignore" });
309
+ const opener = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : "cmd";
310
+ const args = process.platform === "win32" ? ["/c", "start", "", previewUrl] : [previewUrl];
311
+ execFile(opener, args, { timeout: 1e4 }, () => {
312
+ });
316
313
  } catch {
317
314
  }
318
315
  }
@@ -93,10 +93,11 @@ async function launchChrome(options = {}) {
93
93
  "--no-sandbox",
94
94
  "--no-first-run",
95
95
  "--no-default-browser-check",
96
+ "--disable-session-crashed-bubble",
96
97
  "--disable-background-timer-throttling",
97
98
  "--disable-backgrounding-occluded-windows",
98
99
  "--disable-renderer-backgrounding",
99
- "--disable-features=Translate",
100
+ "--disable-features=Translate,PasswordLeakDetection",
100
101
  "--disable-popup-blocking"
101
102
  ];
102
103
  if (headless) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createRuleEngine,
3
3
  launch
4
- } from "./chunk-CLYZPSDR.js";
4
+ } from "./chunk-4OU37CXP.js";
5
5
  import {
6
6
  errMsg
7
7
  } from "./chunk-GDKLH7ZY.js";
@@ -1227,7 +1227,7 @@ async function closeSessionByName(name) {
1227
1227
  } catch {
1228
1228
  }
1229
1229
  try {
1230
- const { SessionRecorder } = await import("./session-recorder-3BEVWHOK.js");
1230
+ const { SessionRecorder } = await import("./session-recorder-GEZVQBKW.js");
1231
1231
  SessionRecorder.cleanup(session.name);
1232
1232
  } catch {
1233
1233
  }
@@ -875,6 +875,55 @@ var ACTION_SIGNAL_SCRIPT = `
875
875
  } catch(e) { /* skip */ }
876
876
  }
877
877
 
878
+ // Ordinal address (r6): ancestor form's ordinal among sibling forms + element's
879
+ // ordinal among same-tag direct children of that form. Direct children only \u2014
880
+ // nested elements have no stable single-level address.
881
+ var ordinal = null;
882
+ try {
883
+ var ordForm = el.closest ? el.closest('form') : null;
884
+ if (ordForm && el.parentElement === ordForm) {
885
+ var ordParent = ordForm.parentElement;
886
+ var formSibs = ordParent
887
+ ? Array.prototype.filter.call(ordParent.children, function(c) { return c.tagName === 'FORM'; })
888
+ : [ordForm];
889
+ var tagSibs = Array.prototype.filter.call(ordForm.children, function(c) { return c.tagName === el.tagName; });
890
+ ordinal = {
891
+ formNth: formSibs.indexOf(ordForm) + 1,
892
+ tagNth: tagSibs.indexOf(el) + 1,
893
+ };
894
+ }
895
+ } catch(e) { /* skip */ }
896
+
897
+ // Label text (r16): the <label> associated with the element (for= association or ancestor wrapper). In virtual list /
898
+ // form-row reordering scenarios, structural ordinals fail, but the label text moves in the same line as the
899
+ // control\u2014content moves, and the anchor follows the content.
900
+ var labelText = '';
901
+ try {
902
+ var lbl = null;
903
+ if (el.id) lbl = el.ownerDocument.querySelector('label[for="' + el.id + '"]');
904
+ if (!lbl && el.closest) lbl = el.closest('label');
905
+ if (lbl) labelText = (lbl.textContent || '').trim().substring(0, 40);
906
+ } catch(e) { /* skip */ }
907
+
908
+ // Element size (r25): rounded rect at record time \u2014 scoring signal for
909
+ // fingerprint disambiguation between same-fingerprint decoys.
910
+ var size = null;
911
+ try {
912
+ var szR = el.getBoundingClientRect();
913
+ if (szR.width > 0 || szR.height > 0) {
914
+ size = { w: Math.round(szR.width), h: Math.round(szR.height) };
915
+ }
916
+ } catch(e) { /* skip */ }
917
+
918
+ // Row text (r27): textContent of the closest table/list row. In virtual
919
+ // lists and sortable tables the row re-indexes \u2014 the row TEXT travels
920
+ // with the content, giving inputs a content anchor that survives reorder.
921
+ var rowText = '';
922
+ try {
923
+ var row = el.closest ? el.closest('tr,li') : null;
924
+ if (row) rowText = (row.textContent || '').trim().replace(/s+/g, ' ').substring(0, 40);
925
+ } catch(e) { /* skip */ }
926
+
878
927
  return {
879
928
  tag: tag,
880
929
  selector: selector,
@@ -888,6 +937,10 @@ var ACTION_SIGNAL_SCRIPT = `
888
937
  placeholder: el.getAttribute('placeholder') || undefined,
889
938
  ariaLabel: el.getAttribute('aria-label') || undefined,
890
939
  href: el.getAttribute('href') ? el.getAttribute('href').substring(0, 80) : undefined,
940
+ ordinal: ordinal || undefined,
941
+ labelText: labelText || undefined,
942
+ size: size || undefined,
943
+ rowText: rowText || undefined,
891
944
  };
892
945
  }
893
946
 
@@ -1525,6 +1578,50 @@ var ACTION_SIGNAL_SCRIPT = `
1525
1578
  __xb_drag_start_pos = { x: e.clientX, y: e.clientY };
1526
1579
  }, true);
1527
1580
  document.addEventListener('drop', function(e) {
1581
+ // sup-s5: OS \u6587\u4EF6\u62D6\u5165\u6355\u83B7\u2014\u2014Dropzone/Uppy \u7C7B\u4E0A\u4F20\u533A\u65E0 input[type=file]\uFF0C
1582
+ // change \u6355\u83B7\u591F\u4E0D\u7740\uFF1BdataTransfer.files \u7ECF FileReader \u5185\u8054\uFF08\u4E0E
1583
+ // filechooser \u540C\u6784\uFF09\uFF0C\u56DE\u653E\u7AEF 'drop' \u52A8\u4F5C\u7ECF dropFiles \u91CD\u653E\u3002
1584
+ try {
1585
+ var dropped = (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0)
1586
+ ? Array.prototype.slice.call(e.dataTransfer.files)
1587
+ : [];
1588
+ if (dropped.length > 0) {
1589
+ var zone = describe(resolveMeaningful(e));
1590
+ var names = dropped.map(function(f) { return f.name; });
1591
+ var readers = [];
1592
+ for (var i = 0; i < dropped.length; i++) {
1593
+ readers.push(new Promise(function(resolve) {
1594
+ var reader = new FileReader();
1595
+ reader.onload = function() { resolve(reader.result); };
1596
+ reader.onerror = function() { resolve(null); };
1597
+ reader.readAsDataURL(dropped[i]);
1598
+ }));
1599
+ }
1600
+ Promise.all(readers).then(function(contents) {
1601
+ var fileData = [];
1602
+ for (var j = 0; j < dropped.length; j++) {
1603
+ fileData.push({
1604
+ name: dropped[j].name,
1605
+ type: dropped[j].type,
1606
+ size: dropped[j].size,
1607
+ dataUrl: contents[j],
1608
+ });
1609
+ }
1610
+ pushAction('drop', {
1611
+ x: e.clientX,
1612
+ y: e.clientY,
1613
+ element: zone,
1614
+ value: names.join(', '),
1615
+ files: {
1616
+ names: names,
1617
+ count: dropped.length,
1618
+ isMultiple: dropped.length > 1,
1619
+ fileData: fileData,
1620
+ },
1621
+ });
1622
+ });
1623
+ }
1624
+ } catch(_) { /* capture must not break the drag path */ }
1528
1625
  if (__xb_drag_source && __xb_drag_start_pos) {
1529
1626
  pushAction('drag', {
1530
1627
  x: e.clientX,
@@ -97,10 +97,11 @@ async function launchChrome(options = {}) {
97
97
  "--no-sandbox",
98
98
  "--no-first-run",
99
99
  "--no-default-browser-check",
100
+ "--disable-session-crashed-bubble",
100
101
  "--disable-background-timer-throttling",
101
102
  "--disable-backgrounding-occluded-windows",
102
103
  "--disable-renderer-backgrounding",
103
- "--disable-features=Translate",
104
+ "--disable-features=Translate,PasswordLeakDetection",
104
105
  "--disable-popup-blocking"
105
106
  ];
106
107
  if (headless) {
@@ -1,5 +1,5 @@
1
1
  // src/human-interaction.ts
2
- import { execSync } from "child_process";
2
+ import { execFile } from "child_process";
3
3
 
4
4
  // src/screencast.ts
5
5
  var ScreencastCapturer = class {
@@ -362,11 +362,6 @@ function resolveScreenshotsDir() {
362
362
  return join(tmpdir(), "xbrowser", "screenshots");
363
363
  }
364
364
 
365
- // src/utils/shell-escape.ts
366
- function shellEscape(value) {
367
- return `'${value.replace(/'/g, "'\\''")}'`;
368
- }
369
-
370
365
  // src/human-interaction.ts
371
366
  var HumanInteractionManager = class {
372
367
  wsServer;
@@ -395,8 +390,10 @@ var HumanInteractionManager = class {
395
390
  tryAutoOpen(previewUrl) {
396
391
  if (!this.autoOpen) return;
397
392
  try {
398
- const cmd = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : "start";
399
- execSync(`${cmd} ${shellEscape(previewUrl)}`, { stdio: "ignore" });
393
+ const opener = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : "cmd";
394
+ const args = process.platform === "win32" ? ["/c", "start", "", previewUrl] : [previewUrl];
395
+ execFile(opener, args, { timeout: 1e4 }, () => {
396
+ });
400
397
  } catch {
401
398
  }
402
399
  }