@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.
- package/dist/{anti-bot-DR56Y63V.js → anti-bot-GTTYNEFB.js} +1 -1
- package/dist/{browser-WQZ3D6AE.js → browser-3HQKDZQ6.js} +4 -2
- package/dist/{browser-T3V3JWVH.js → browser-ILXTEWH4.js} +1 -1
- package/dist/{browser-HBL72GPZ.js → browser-XPDMY2NX.js} +3 -3
- package/dist/{cdp-driver-J3YQ4LJV.js → cdp-driver-ESH3PDE6.js} +2 -1
- package/dist/cdp-driver-N2E2ZNSC.js +4644 -0
- package/dist/cdp-driver-YIKR4BUX.js +49 -0
- package/dist/chunk-3FWLW7FS.js +106 -0
- package/dist/chunk-A6LPGFAL.js +437 -0
- package/dist/{chunk-RRBXV7KE.js → chunk-DKM2JOZL.js} +633 -63
- package/dist/{chunk-ABXMBNQ6.js → chunk-H2A5JUK5.js} +37 -466
- package/dist/{chunk-5UGR6MUK.js → chunk-HBHOKZPN.js} +51 -16
- package/dist/{chunk-BNO7OKO4.js → chunk-HBMEFSTB.js} +39 -0
- package/dist/{chunk-INTQPBYF.js → chunk-JKVUFP3G.js} +6 -2
- package/dist/chunk-KJTABK3Z.js +1255 -0
- package/dist/{chunk-DWDXEGVK.js → chunk-NKW4A74J.js} +9 -3
- package/dist/{chunk-4452SPFI.js → chunk-NODRQGOK.js} +51 -16
- package/dist/{chunk-SQHSZENE.js → chunk-OMU63E6J.js} +3 -22
- package/dist/{chunk-NITFVWWS.js → chunk-OVW2UEWN.js} +981 -407
- package/dist/{chunk-WSCP7QCJ.js → chunk-R6IJ6PIV.js} +14 -11
- package/dist/{chunk-YMUSHPU4.js → chunk-SH6OTPXN.js} +46 -16
- package/dist/{chunk-MWFHZUIY.js → chunk-TEXCXIBW.js} +1 -1
- package/dist/{cdp-driver-2T4P4ZE2.js → chunk-Z6CUR3VG.js} +1542 -134
- package/dist/{chunk-IIM5GOD7.js → chunk-ZTHE5RBZ.js} +7 -1
- package/dist/cli.js +1136 -584
- package/dist/{daemon-client-GKEPT4NY.js → daemon-client-7D6EZNOE.js} +46 -16
- package/dist/{daemon-client-O6BYVRXV.js → daemon-client-HEGAXWGK.js} +1 -1
- package/dist/daemon-main.js +1031 -522
- package/dist/{human-interaction-5AO42MBA.js → human-interaction-4YR2N6R6.js} +2 -2
- package/dist/{human-interaction-C5OEGXGO.js → human-interaction-Y5IDH6LD.js} +1 -1
- package/dist/{human-interaction-ISXZTAYY.js → human-interaction-ZUTR5AC2.js} +2 -2
- package/dist/index.d.ts +10 -0
- package/dist/index.js +1147 -593
- package/dist/{proxy-C6CK3UH5.js → proxy-LUR4U5YF.js} +2 -1
- package/dist/{recovery-J2ISVGUL.js → recovery-FTZGV6VY.js} +2 -2
- package/dist/{recovery-ZJVVHP7N.js → recovery-L5GLDX4O.js} +1 -1
- package/dist/{recovery-EF33LKRJ.js → recovery-Z3RDZENA.js} +2 -2
- package/dist/{session-recorder-H3KEYU26.js → session-recorder-3BEVWHOK.js} +1 -1
- package/dist/{session-recorder-QRZMKFVL.js → session-recorder-SLDBENVF.js} +1 -1
- package/dist/{session-replayer-LJUC4TI7.js → session-replayer-K4A6OI4M.js} +90 -2
- package/package.json +1 -1
- 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
|
|
2007
|
-
if (
|
|
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
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
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() +
|
|
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
|
|
2750
|
-
if (
|
|
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() +
|
|
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
|
-
|
|
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, "'\\''")}'`;
|