@xbrowser/cli 1.10.0 → 1.12.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 (42) hide show
  1. package/dist/{anti-bot-DR56Y63V.js → anti-bot-GTTYNEFB.js} +1 -1
  2. package/dist/{browser-WQZ3D6AE.js → browser-3HQKDZQ6.js} +4 -2
  3. package/dist/{browser-T3V3JWVH.js → browser-ILXTEWH4.js} +1 -1
  4. package/dist/{browser-HBL72GPZ.js → browser-XPDMY2NX.js} +3 -3
  5. package/dist/{cdp-driver-J3YQ4LJV.js → cdp-driver-ESH3PDE6.js} +2 -1
  6. package/dist/cdp-driver-N2E2ZNSC.js +4644 -0
  7. package/dist/cdp-driver-YIKR4BUX.js +49 -0
  8. package/dist/chunk-3FWLW7FS.js +106 -0
  9. package/dist/chunk-A6LPGFAL.js +437 -0
  10. package/dist/{chunk-RRBXV7KE.js → chunk-DKM2JOZL.js} +633 -63
  11. package/dist/{chunk-ABXMBNQ6.js → chunk-H2A5JUK5.js} +37 -466
  12. package/dist/{chunk-5UGR6MUK.js → chunk-HBHOKZPN.js} +51 -16
  13. package/dist/{chunk-BNO7OKO4.js → chunk-HBMEFSTB.js} +39 -0
  14. package/dist/{chunk-INTQPBYF.js → chunk-JKVUFP3G.js} +6 -2
  15. package/dist/chunk-KJTABK3Z.js +1255 -0
  16. package/dist/{chunk-DWDXEGVK.js → chunk-NKW4A74J.js} +9 -3
  17. package/dist/{chunk-4452SPFI.js → chunk-NODRQGOK.js} +51 -16
  18. package/dist/{chunk-SQHSZENE.js → chunk-OMU63E6J.js} +3 -22
  19. package/dist/{chunk-NITFVWWS.js → chunk-OVW2UEWN.js} +981 -407
  20. package/dist/{chunk-WSCP7QCJ.js → chunk-R6IJ6PIV.js} +14 -11
  21. package/dist/{chunk-YMUSHPU4.js → chunk-SH6OTPXN.js} +46 -16
  22. package/dist/{chunk-MWFHZUIY.js → chunk-TEXCXIBW.js} +1 -1
  23. package/dist/{cdp-driver-2T4P4ZE2.js → chunk-Z6CUR3VG.js} +1542 -134
  24. package/dist/{chunk-IIM5GOD7.js → chunk-ZTHE5RBZ.js} +7 -1
  25. package/dist/cli.js +1136 -584
  26. package/dist/{daemon-client-GKEPT4NY.js → daemon-client-7D6EZNOE.js} +46 -16
  27. package/dist/{daemon-client-O6BYVRXV.js → daemon-client-HEGAXWGK.js} +1 -1
  28. package/dist/daemon-main.js +1031 -522
  29. package/dist/{human-interaction-5AO42MBA.js → human-interaction-4YR2N6R6.js} +2 -2
  30. package/dist/{human-interaction-C5OEGXGO.js → human-interaction-Y5IDH6LD.js} +1 -1
  31. package/dist/{human-interaction-ISXZTAYY.js → human-interaction-ZUTR5AC2.js} +2 -2
  32. package/dist/index.d.ts +10 -0
  33. package/dist/index.js +1147 -593
  34. package/dist/{proxy-C6CK3UH5.js → proxy-LUR4U5YF.js} +2 -1
  35. package/dist/{recovery-J2ISVGUL.js → recovery-FTZGV6VY.js} +2 -2
  36. package/dist/{recovery-ZJVVHP7N.js → recovery-L5GLDX4O.js} +1 -1
  37. package/dist/{recovery-EF33LKRJ.js → recovery-Z3RDZENA.js} +2 -2
  38. package/dist/{session-recorder-H3KEYU26.js → session-recorder-3BEVWHOK.js} +1 -1
  39. package/dist/{session-recorder-QRZMKFVL.js → session-recorder-SLDBENVF.js} +1 -1
  40. package/dist/{session-replayer-LJUC4TI7.js → session-replayer-K4A6OI4M.js} +90 -2
  41. package/package.json +1 -1
  42. package/dist/chunk-BAHSRZIX.js +0 -2191
@@ -356,6 +356,11 @@ function getCaptchaConfig() {
356
356
  previewPort: parseInt(process.env.XBROWSER_PREVIEW_PORT || "") || config.preview?.port || 9223
357
357
  };
358
358
  }
359
+ function resolveScreenshotsDir() {
360
+ const configured = getConfigValue("screenshots.dir");
361
+ if (typeof configured === "string" && configured.trim()) return configured.trim();
362
+ return join(tmpdir(), "xbrowser", "screenshots");
363
+ }
359
364
 
360
365
  // src/utils/shell-escape.ts
361
366
  function shellEscape(value) {
@@ -508,9 +513,6 @@ var HumanInteractionManager = class {
508
513
  };
509
514
 
510
515
  export {
511
- ScreencastCapturer,
512
- CaptchaDetector,
513
- WebhookNotifier,
514
516
  loadConfig,
515
517
  getConfigValue,
516
518
  setConfigValue,
@@ -519,5 +521,9 @@ export {
519
521
  getMarketplaceUrl,
520
522
  resolveNpmPackageWithFallback,
521
523
  getCaptchaConfig,
524
+ resolveScreenshotsDir,
525
+ ScreencastCapturer,
526
+ CaptchaDetector,
527
+ WebhookNotifier,
522
528
  HumanInteractionManager
523
529
  };
@@ -1093,6 +1093,33 @@ var ACTION_SIGNAL_SCRIPT = `
1093
1093
  }
1094
1094
  }, true);
1095
1095
 
1096
+ // \u2500\u2500 Pointer-based drag (modern sliders, sortable lists) \u2500\u2500
1097
+ // HTML5 dragstart/drop never fires for pointer-driven drags \u2014 capture via
1098
+ // pointerdown/pointerup with a movement threshold instead (rec-duel d08).
1099
+ var __xb_ptr_down = null;
1100
+ document.addEventListener('pointerdown', function(e) {
1101
+ var t = actualTarget(e);
1102
+ __xb_ptr_down = { x: e.clientX, y: e.clientY, element: describe(t), ts: Date.now() };
1103
+ }, true);
1104
+ document.addEventListener('pointerup', function(e) {
1105
+ if (!__xb_ptr_down) return;
1106
+ var start = __xb_ptr_down;
1107
+ __xb_ptr_down = null;
1108
+ var dx = e.clientX - start.x, dy = e.clientY - start.y;
1109
+ if (Math.abs(dx) < 15 && Math.abs(dy) < 15) return; // tap/click, not a drag
1110
+ pushAction('drag', {
1111
+ x: e.clientX,
1112
+ y: e.clientY,
1113
+ element: start.element,
1114
+ drag: {
1115
+ fromX: start.x,
1116
+ fromY: start.y,
1117
+ toX: e.clientX,
1118
+ toY: e.clientY,
1119
+ },
1120
+ });
1121
+ }, true);
1122
+
1096
1123
  // \u2500\u2500 Drag & drop \u2500\u2500
1097
1124
  var __xb_drag_source = null;
1098
1125
  var __xb_drag_start_pos = null;
@@ -1985,8 +2012,7 @@ var SessionRecorder = class _SessionRecorder {
1985
2012
  "resize",
1986
2013
  "clipboard",
1987
2014
  "touch",
1988
- "contextmenu",
1989
- "drag"
2015
+ "contextmenu"
1990
2016
  ]);
1991
2017
  constructor(context, page, sessionName) {
1992
2018
  this.context = context;
@@ -2003,8 +2029,8 @@ var SessionRecorder = class _SessionRecorder {
2003
2029
  async recordCommandAction(action) {
2004
2030
  const dedupFromAction = this.dedupKey(action.type, action.selector, action.element?.tag, action.value);
2005
2031
  if (dedupFromAction) {
2006
- const expires = this.dedupMap.get(dedupFromAction);
2007
- if (expires && Date.now() < expires) {
2032
+ const entry = this.dedupMap.get(dedupFromAction);
2033
+ if (entry && entry.origin === "signal" && Date.now() < entry.expires) {
2008
2034
  return;
2009
2035
  }
2010
2036
  }
@@ -2021,19 +2047,25 @@ var SessionRecorder = class _SessionRecorder {
2021
2047
  value: action.value
2022
2048
  };
2023
2049
  this.actions.push(actionToPush);
2024
- actionToPush.elementScreenshot = await this.captureElementScreenshot(this.page, {
2025
- type: action.type,
2026
- element: actionToPush.element
2027
- });
2028
- await this.captureAutoSnapshot(this.page, actionToPush, "after").catch(() => {
2029
- });
2050
+ actionToPush.elementScreenshot = await Promise.race([
2051
+ this.captureElementScreenshot(this.page, {
2052
+ type: action.type,
2053
+ element: actionToPush.element
2054
+ }).catch(() => void 0),
2055
+ new Promise((r) => setTimeout(r, 3e3))
2056
+ ]);
2057
+ await Promise.race([
2058
+ this.captureAutoSnapshot(this.page, actionToPush, "after").catch(() => {
2059
+ }),
2060
+ new Promise((r) => setTimeout(r, 6e3))
2061
+ ]);
2030
2062
  this.lastActionTs = ts;
2031
- this.dedupMap.set(dedupFromAction, Date.now() + 2e3);
2063
+ this.dedupMap.set(dedupFromAction, { expires: Date.now() + 4e3, origin: "command" });
2032
2064
  this.dedupActionCount++;
2033
2065
  if (this.dedupActionCount % 200 === 0) {
2034
2066
  const now = Date.now();
2035
2067
  for (const [k, v] of this.dedupMap) {
2036
- if (now >= v) this.dedupMap.delete(k);
2068
+ if (now >= v.expires) this.dedupMap.delete(k);
2037
2069
  }
2038
2070
  }
2039
2071
  if (action.url && action.url !== "about:blank") {
@@ -2746,8 +2778,8 @@ var SessionRecorder = class _SessionRecorder {
2746
2778
  }
2747
2779
  const dedupFromSignal = this.dedupKey(raw.type, raw.element?.selector, raw.element?.tag, raw.value);
2748
2780
  if (dedupFromSignal) {
2749
- const expires = this.dedupMap.get(dedupFromSignal);
2750
- if (expires && Date.now() < expires) {
2781
+ const entry = this.dedupMap.get(dedupFromSignal);
2782
+ if (entry && entry.origin === "command" && Date.now() < entry.expires) {
2751
2783
  continue;
2752
2784
  }
2753
2785
  }
@@ -2790,7 +2822,10 @@ var SessionRecorder = class _SessionRecorder {
2790
2822
  // run before the last sample lands — passthrough keeps whatever has
2791
2823
  // been collected so far.
2792
2824
  hoverContext: raw.hoverContext,
2793
- files: raw.files
2825
+ files: raw.files,
2826
+ // Pointer-drag payload (fromX/fromY/toX/toY) — replayer replays the
2827
+ // drag from these coordinates; dropping it made drags no-ops (d08)
2828
+ drag: raw.drag
2794
2829
  });
2795
2830
  const pushed = this.actions[this.actions.length - 1];
2796
2831
  pushed.elementScreenshot = await this.captureElementScreenshot(page, raw);
@@ -2799,7 +2834,7 @@ var SessionRecorder = class _SessionRecorder {
2799
2834
  this.lastActionTs = raw.ts;
2800
2835
  const dedupKey = this.dedupKey(raw.type, raw.element?.selector, raw.element?.tag, raw.value);
2801
2836
  if (dedupKey) {
2802
- this.dedupMap.set(dedupKey, Date.now() + 2e3);
2837
+ this.dedupMap.set(dedupKey, { expires: Date.now() + 4e3, origin: "signal" });
2803
2838
  this.dedupActionCount++;
2804
2839
  }
2805
2840
  const verifyTypes = /* @__PURE__ */ new Set(["click", "submit", "input", "change", "cdp-click", "cdp-fill"]);
@@ -1,6 +1,7 @@
1
1
  import {
2
- ScreencastCapturer
3
- } from "./chunk-BNO7OKO4.js";
2
+ ScreencastCapturer,
3
+ getCaptchaConfig
4
+ } from "./chunk-HBMEFSTB.js";
4
5
 
5
6
  // src/human-interaction.ts
6
7
  import { execSync } from "child_process";
@@ -137,26 +138,6 @@ var WebhookNotifier = class {
137
138
  }
138
139
  };
139
140
 
140
- // src/config.ts
141
- import { homedir, tmpdir } from "os";
142
- import { join } from "path";
143
- import { loadConfig as coreLoadConfig, saveConfig as coreSaveConfig } from "@dyyz1993/xcli-core";
144
- function getConfigSource() {
145
- return { configDir: join(homedir() || tmpdir(), ".xbrowser") };
146
- }
147
- function loadConfig() {
148
- return coreLoadConfig(getConfigSource());
149
- }
150
- function getCaptchaConfig() {
151
- const config = loadConfig();
152
- return {
153
- notifyUrl: process.env.XBROWSER_NOTIFY_URL || config.captcha?.notifyUrl,
154
- autoOpen: process.env.XBROWSER_AUTO_OPEN === "true" || config.captcha?.autoOpen === true,
155
- timeout: parseInt(process.env.XBROWSER_CAPTCHA_TIMEOUT || "") || config.captcha?.timeout || 120,
156
- previewPort: parseInt(process.env.XBROWSER_PREVIEW_PORT || "") || config.preview?.port || 9223
157
- };
158
- }
159
-
160
141
  // src/utils/shell-escape.ts
161
142
  function shellEscape(value) {
162
143
  return `'${value.replace(/'/g, "'\\''")}'`;