@xbrowser/cli 1.14.0 → 1.16.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/{browser-KJWBHGHX.js → browser-3KTEVTMU.js} +2 -2
- package/dist/{browser-5A6AL62M.js → browser-AOVQTGJ7.js} +2 -2
- package/dist/{browser-DI6UQN6Q.js → browser-KT4FOWBO.js} +1 -1
- package/dist/{cdp-driver-QXTXJZH7.js → cdp-driver-ALDP2CZT.js} +248 -49
- package/dist/{cdp-driver-4SFS6GNY.js → cdp-driver-DKNLIA6B.js} +1 -1
- package/dist/{cdp-driver-AHKUT57K.js → cdp-driver-OC37OT4B.js} +1 -1
- package/dist/{chunk-BTFKJD7Z.js → chunk-5EYOEB4R.js} +277 -65
- package/dist/{chunk-B753M33E.js → chunk-7V3B7VPX.js} +9 -7
- package/dist/{chunk-PYQGDBAF.js → chunk-A5HJ6IRE.js} +269 -59
- package/dist/{chunk-ZD4OSYOX.js → chunk-GWQ5NTVE.js} +9 -7
- package/dist/{chunk-UPAWITVM.js → chunk-LTBNQERK.js} +269 -59
- package/dist/cli.js +86 -32
- package/dist/clipboard-BOL2GP2E.js +58 -0
- package/dist/clipboard-XRP54ENE.js +58 -0
- package/dist/daemon-main.js +44 -22
- package/dist/index.d.ts +4 -0
- package/dist/index.js +106 -51
- package/dist/{session-replayer-I3PJFO3H.js → session-replayer-MJH5W7BB.js} +1 -1
- package/package.json +1 -1
- package/dist/{recovery-Z3RDZENA.js → recovery-MDWAVXE4.js} +4 -4
- package/dist/{recovery-FTZGV6VY.js → recovery-NXC35EQN.js} +4 -4
package/dist/index.js
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
filterRecording,
|
|
3
|
+
parseExcludeTypes
|
|
4
|
+
} from "./chunk-ANVL2ID2.js";
|
|
5
|
+
import {
|
|
6
|
+
closeAllSessions,
|
|
7
|
+
closeEphemeralContext,
|
|
8
|
+
closeSessionByName,
|
|
9
|
+
createEphemeralContext,
|
|
10
|
+
createSession,
|
|
11
|
+
destroyBrowser,
|
|
12
|
+
findOrRestoreSession,
|
|
13
|
+
findSession,
|
|
14
|
+
getAllSessions,
|
|
15
|
+
getBrowser,
|
|
16
|
+
getSessionById,
|
|
17
|
+
resetForTesting,
|
|
18
|
+
resolveLaunchOpts,
|
|
19
|
+
saveSessionDiskMeta,
|
|
20
|
+
setActivePage
|
|
21
|
+
} from "./chunk-7V3B7VPX.js";
|
|
1
22
|
import {
|
|
2
23
|
detectAntiBot,
|
|
3
24
|
formatDetectionMessage
|
|
@@ -62,38 +83,10 @@ import {
|
|
|
62
83
|
printExtractSummary
|
|
63
84
|
} from "./chunk-X46HDAOT.js";
|
|
64
85
|
import {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
SessionRecorder
|
|
70
|
-
} from "./chunk-NODRQGOK.js";
|
|
71
|
-
import {
|
|
72
|
-
addKnownIssue,
|
|
73
|
-
getKnowledgePath,
|
|
74
|
-
init_site_knowledge,
|
|
75
|
-
listSiteKnowledge,
|
|
76
|
-
readSiteKnowledge,
|
|
77
|
-
readSiteKnowledgeMarkdown
|
|
78
|
-
} from "./chunk-OZKD3W4X.js";
|
|
79
|
-
import {
|
|
80
|
-
closeAllSessions,
|
|
81
|
-
closeEphemeralContext,
|
|
82
|
-
closeSessionByName,
|
|
83
|
-
createEphemeralContext,
|
|
84
|
-
createSession,
|
|
85
|
-
destroyBrowser,
|
|
86
|
-
findOrRestoreSession,
|
|
87
|
-
findSession,
|
|
88
|
-
getAllSessions,
|
|
89
|
-
getBrowser,
|
|
90
|
-
getSessionById,
|
|
91
|
-
resetForTesting,
|
|
92
|
-
resolveLaunchOpts,
|
|
93
|
-
saveSessionDiskMeta,
|
|
94
|
-
setActivePage
|
|
95
|
-
} from "./chunk-B753M33E.js";
|
|
96
|
-
import "./chunk-PYQGDBAF.js";
|
|
86
|
+
rand,
|
|
87
|
+
sleep,
|
|
88
|
+
wheelDelta
|
|
89
|
+
} from "./chunk-A5HJ6IRE.js";
|
|
97
90
|
import "./chunk-TNEN6VQ2.js";
|
|
98
91
|
import {
|
|
99
92
|
errMsg
|
|
@@ -114,6 +107,17 @@ import {
|
|
|
114
107
|
networkAnomalyRule,
|
|
115
108
|
pageLifecycleRule
|
|
116
109
|
} from "./chunk-H2A5JUK5.js";
|
|
110
|
+
import {
|
|
111
|
+
SessionRecorder
|
|
112
|
+
} from "./chunk-NODRQGOK.js";
|
|
113
|
+
import {
|
|
114
|
+
addKnownIssue,
|
|
115
|
+
getKnowledgePath,
|
|
116
|
+
init_site_knowledge,
|
|
117
|
+
listSiteKnowledge,
|
|
118
|
+
readSiteKnowledge,
|
|
119
|
+
readSiteKnowledgeMarkdown
|
|
120
|
+
} from "./chunk-OZKD3W4X.js";
|
|
117
121
|
import {
|
|
118
122
|
__require
|
|
119
123
|
} from "./chunk-KFQGP6VL.js";
|
|
@@ -385,7 +389,8 @@ var gotoCommand = registerCommand({
|
|
|
385
389
|
parameters: z.object({
|
|
386
390
|
url: z.string(),
|
|
387
391
|
waitUntil: z.enum(["load", "domcontentloaded", "networkidle", "commit"]).optional(),
|
|
388
|
-
timeout: z.number().optional()
|
|
392
|
+
timeout: z.number().optional(),
|
|
393
|
+
referrer: z.string().optional()
|
|
389
394
|
}),
|
|
390
395
|
result: z.object({
|
|
391
396
|
url: z.string(),
|
|
@@ -406,7 +411,9 @@ var gotoCommand = registerCommand({
|
|
|
406
411
|
try {
|
|
407
412
|
response = await ctx.page.goto(url, {
|
|
408
413
|
waitUntil: p.waitUntil || "domcontentloaded",
|
|
409
|
-
...p.timeout ? { timeout: p.timeout } : {}
|
|
414
|
+
...p.timeout ? { timeout: p.timeout } : {},
|
|
415
|
+
// referrer(d54):模拟从源页面点链接进入 —— document.referrer 非空
|
|
416
|
+
...p.referrer ? { referer: p.referrer } : {}
|
|
410
417
|
});
|
|
411
418
|
} catch (err) {
|
|
412
419
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -933,21 +940,34 @@ var scrollCommand = registerCommand({
|
|
|
933
940
|
}),
|
|
934
941
|
handler: async (p, ctx) => {
|
|
935
942
|
const distance = p.distance ?? 500;
|
|
936
|
-
const
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
right: [distance, 0],
|
|
940
|
-
left: [-distance, 0]
|
|
941
|
-
};
|
|
942
|
-
const [dx, dy] = deltas[p.direction];
|
|
943
|
+
const sign = { down: 1, up: -1, right: 1, left: -1 };
|
|
944
|
+
const vertical = p.direction === "down" || p.direction === "up";
|
|
945
|
+
const s = sign[p.direction];
|
|
943
946
|
if (p.selector) {
|
|
944
947
|
const element = ctx.page.locator(p.selector).first();
|
|
945
948
|
await element.evaluate((el, args) => {
|
|
946
949
|
const [dxx, dyy] = args;
|
|
947
950
|
el.scrollBy(dxx, dyy);
|
|
948
|
-
}, [
|
|
951
|
+
}, [vertical ? 0 : distance * s, vertical ? distance * s : 0]);
|
|
952
|
+
} else if (process.env.XBROWSER_STEALTH !== "off") {
|
|
953
|
+
let acc = 0;
|
|
954
|
+
let step = 0;
|
|
955
|
+
while (acc < distance && step < 60) {
|
|
956
|
+
const d = Math.min(wheelDelta(step), distance - acc);
|
|
957
|
+
if (d < 1) break;
|
|
958
|
+
await ctx.page.mouse.wheel(
|
|
959
|
+
vertical ? 0 : d * s,
|
|
960
|
+
vertical ? d * s : 0
|
|
961
|
+
);
|
|
962
|
+
acc += d;
|
|
963
|
+
step++;
|
|
964
|
+
await sleep(rand(16, 28));
|
|
965
|
+
}
|
|
949
966
|
} else {
|
|
950
|
-
await ctx.page.mouse.wheel(
|
|
967
|
+
await ctx.page.mouse.wheel(
|
|
968
|
+
vertical ? 0 : distance * s,
|
|
969
|
+
vertical ? distance * s : 0
|
|
970
|
+
);
|
|
951
971
|
}
|
|
952
972
|
return ok5({ direction: p.direction, distance });
|
|
953
973
|
}
|
|
@@ -7873,7 +7893,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7873
7893
|
}
|
|
7874
7894
|
let targetPageOverride = null;
|
|
7875
7895
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7876
|
-
const { findTargetPage } = await import("./browser-
|
|
7896
|
+
const { findTargetPage } = await import("./browser-3KTEVTMU.js");
|
|
7877
7897
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7878
7898
|
if (!targetPageOverride) {
|
|
7879
7899
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -8153,6 +8173,9 @@ async function executeChain(input, options) {
|
|
|
8153
8173
|
for (const pipeline of pipelines) {
|
|
8154
8174
|
const { type, pipeline: commands } = pipeline;
|
|
8155
8175
|
for (const cmdStr of commands) {
|
|
8176
|
+
if (process.env.XBROWSER_CHAIN_PACE === "human" && results.length > 0) {
|
|
8177
|
+
await new Promise((r) => setTimeout(r, 800 + Math.random() * 1700));
|
|
8178
|
+
}
|
|
8156
8179
|
const parts = splitCommand(cmdStr);
|
|
8157
8180
|
if (parts.length === 0) continue;
|
|
8158
8181
|
const cmdName = parts[0];
|
|
@@ -10561,12 +10584,33 @@ function normalizeSelector(input) {
|
|
|
10561
10584
|
|
|
10562
10585
|
// src/cli/browser-routes.ts
|
|
10563
10586
|
import { helpGenerator } from "@dyyz1993/xcli-core";
|
|
10587
|
+
function autoCompleteParams(cmdName, params, options) {
|
|
10588
|
+
try {
|
|
10589
|
+
const cmd = getCommand(cmdName);
|
|
10590
|
+
if (!cmd?.parameters) return params;
|
|
10591
|
+
const schema = asZodSchema(cmd.parameters);
|
|
10592
|
+
const shape = schema?.shape ?? schema?._def?.shape;
|
|
10593
|
+
if (!shape) return params;
|
|
10594
|
+
for (const key of Object.keys(shape)) {
|
|
10595
|
+
if (params[key] !== void 0) continue;
|
|
10596
|
+
const v = options[key];
|
|
10597
|
+
if (v === void 0 || v === true && key === "json" || key === "yaml") continue;
|
|
10598
|
+
if (typeof v === "string" && v === "") continue;
|
|
10599
|
+
params[key] = v;
|
|
10600
|
+
}
|
|
10601
|
+
return params;
|
|
10602
|
+
} catch {
|
|
10603
|
+
return params;
|
|
10604
|
+
}
|
|
10605
|
+
}
|
|
10564
10606
|
function parseSelectorFlags(args, options) {
|
|
10565
|
-
const
|
|
10566
|
-
const
|
|
10607
|
+
const rawSelector = options.s ?? options.selector;
|
|
10608
|
+
const rawValue = options.v ?? options.value;
|
|
10609
|
+
const selector = typeof rawSelector === "string" ? normalizeSelector(rawSelector) : void 0;
|
|
10610
|
+
const value = typeof rawValue === "string" ? rawValue : void 0;
|
|
10567
10611
|
const remaining = args.filter((a) => !a.startsWith("-"));
|
|
10568
10612
|
return {
|
|
10569
|
-
selector
|
|
10613
|
+
selector,
|
|
10570
10614
|
value,
|
|
10571
10615
|
remaining
|
|
10572
10616
|
};
|
|
@@ -10654,7 +10698,11 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
10654
10698
|
if (!sel || !txt)
|
|
10655
10699
|
outputError("Usage: xbrowser type <selector> <text>\n xbrowser type -s <selector> -v <text>");
|
|
10656
10700
|
cmdName = "type";
|
|
10657
|
-
params = {
|
|
10701
|
+
params = {
|
|
10702
|
+
selector: sel,
|
|
10703
|
+
text: txt,
|
|
10704
|
+
...options.delay !== void 0 ? { delay: Number(options.delay) } : {}
|
|
10705
|
+
};
|
|
10658
10706
|
break;
|
|
10659
10707
|
}
|
|
10660
10708
|
case "press": {
|
|
@@ -10796,7 +10844,13 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
10796
10844
|
outputError("Usage: xbrowser mouse <move|click|dblclick> <x> <y>\n xbrowser mouse --action <action> --x <x> --y <y>");
|
|
10797
10845
|
}
|
|
10798
10846
|
cmdName = "mouse";
|
|
10799
|
-
params = {
|
|
10847
|
+
params = {
|
|
10848
|
+
action,
|
|
10849
|
+
x,
|
|
10850
|
+
y,
|
|
10851
|
+
...options.button ? { button: options.button } : {},
|
|
10852
|
+
...options.steps !== void 0 ? { steps: Number(options.steps) } : {}
|
|
10853
|
+
};
|
|
10800
10854
|
break;
|
|
10801
10855
|
}
|
|
10802
10856
|
case "html":
|
|
@@ -10998,6 +11052,7 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
10998
11052
|
if (target) {
|
|
10999
11053
|
params = { ...params, _target: target };
|
|
11000
11054
|
}
|
|
11055
|
+
params = autoCompleteParams(cmdName, params, options);
|
|
11001
11056
|
const tabIndex = options.tab;
|
|
11002
11057
|
if (tabIndex !== void 0) {
|
|
11003
11058
|
params = { ...params, _tabIndex: Number(tabIndex) };
|
|
@@ -14051,7 +14106,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
|
|
|
14051
14106
|
const targetPage = pages[cmdTabIndex];
|
|
14052
14107
|
await targetPage.bringToFront().catch(() => {
|
|
14053
14108
|
});
|
|
14054
|
-
const { setActivePage: setActivePage2 } = await import("./browser-
|
|
14109
|
+
const { setActivePage: setActivePage2 } = await import("./browser-3KTEVTMU.js");
|
|
14055
14110
|
setActivePage2(session, targetPage);
|
|
14056
14111
|
}
|
|
14057
14112
|
}
|
|
@@ -17224,7 +17279,7 @@ var DataCollector = class {
|
|
|
17224
17279
|
return results;
|
|
17225
17280
|
}
|
|
17226
17281
|
async createBrowserContext() {
|
|
17227
|
-
const { launch } = await import("./cdp-driver-
|
|
17282
|
+
const { launch } = await import("./cdp-driver-OC37OT4B.js");
|
|
17228
17283
|
const { browser } = await launch({
|
|
17229
17284
|
headless: true,
|
|
17230
17285
|
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-
|
|
37
|
+
const { launch } = await import("./cdp-driver-DKNLIA6B.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.
|
|
3
|
+
"version": "1.16.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": {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildViewerUrl
|
|
3
|
-
} from "./chunk-TZPKFUBT.js";
|
|
4
|
-
import "./chunk-CG3D3CHY.js";
|
|
5
1
|
import {
|
|
6
2
|
HumanInteractionManager
|
|
7
3
|
} from "./chunk-OMU63E6J.js";
|
|
4
|
+
import {
|
|
5
|
+
buildViewerUrl
|
|
6
|
+
} from "./chunk-TZPKFUBT.js";
|
|
8
7
|
import "./chunk-HBMEFSTB.js";
|
|
8
|
+
import "./chunk-CG3D3CHY.js";
|
|
9
9
|
import "./chunk-KFQGP6VL.js";
|
|
10
10
|
|
|
11
11
|
// src/recovery.ts
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildViewerUrl
|
|
3
|
-
} from "./chunk-3OD76SUE.js";
|
|
4
|
-
import "./chunk-Q2DFJQGS.js";
|
|
5
1
|
import {
|
|
6
2
|
HumanInteractionManager
|
|
7
3
|
} from "./chunk-TEXCXIBW.js";
|
|
4
|
+
import {
|
|
5
|
+
buildViewerUrl
|
|
6
|
+
} from "./chunk-3OD76SUE.js";
|
|
8
7
|
import "./chunk-ZTHE5RBZ.js";
|
|
8
|
+
import "./chunk-Q2DFJQGS.js";
|
|
9
9
|
import "./chunk-KFQGP6VL.js";
|
|
10
10
|
|
|
11
11
|
// src/recovery.ts
|