@xbrowser/cli 1.4.3 → 1.4.5
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/README.md +1 -1
- package/dist/{browser-MPMDAGZY.js → browser-2OALOLR2.js} +2 -2
- package/dist/{browser-B5W577GO.js → browser-5CM4GUZU.js} +1 -1
- package/dist/{browser-VWKGCFA5.js → browser-V3VHXQQF.js} +2 -2
- package/dist/{cdp-driver-TMMK2YYE.js → cdp-driver-ACRHJMS3.js} +12 -2
- package/dist/{cdp-driver-RCRYKHVQ.js → cdp-driver-VRXHK6P6.js} +1 -1
- package/dist/{chunk-WI3XE4W3.js → chunk-IDJ5NILK.js} +12 -2
- package/dist/{chunk-O4HCWMU2.js → chunk-NW3WE5JK.js} +31 -15
- package/dist/{chunk-J3VNBG25.js → chunk-SMRIC22G.js} +20 -14
- package/dist/{chunk-JLSKMNMN.js → chunk-Z6GGTJL5.js} +20 -14
- package/dist/cli.js +27 -29
- package/dist/daemon-main.js +17 -9
- package/dist/index.js +28 -30
- package/dist/{session-replayer-X3S47AA3.js → session-replayer-F4ORJMCL.js} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# xbrowser
|
|
2
2
|
|
|
3
|
-
> **Browser automation CLI** for web scraping, headless browsing, SEO analysis, and AI agent workflows.
|
|
3
|
+
> **Browser automation CLI** for web scraping, headless browsing, SEO analysis, and AI agent workflows. 51 commands, 70+ plugins. A command-line alternative to Playwright, Puppeteer, and Selenium — **no code required**.
|
|
4
4
|
|
|
5
5
|
[](https://github.com/dyyz1993/xbrowser/actions)
|
|
6
6
|
[](https://codecov.io/gh/dyyz1993/xbrowser)
|
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-Z6GGTJL5.js";
|
|
24
|
+
import "./chunk-IDJ5NILK.js";
|
|
25
25
|
import "./chunk-TNEN6VQ2.js";
|
|
26
26
|
import "./chunk-GDKLH7ZY.js";
|
|
27
27
|
import "./chunk-ABXMBNQ6.js";
|
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-SMRIC22G.js";
|
|
24
|
+
import "./chunk-IDJ5NILK.js";
|
|
25
25
|
import "./chunk-TNEN6VQ2.js";
|
|
26
26
|
import "./chunk-GDKLH7ZY.js";
|
|
27
27
|
import "./chunk-KFQGP6VL.js";
|
|
@@ -1167,11 +1167,21 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1167
1167
|
}
|
|
1168
1168
|
async goBack(opts = {}) {
|
|
1169
1169
|
await this.evaluate("() => history.back()");
|
|
1170
|
-
await this.waitForLoadState(opts.waitUntil ?? "
|
|
1170
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 5e3).catch(() => {
|
|
1171
|
+
});
|
|
1172
|
+
try {
|
|
1173
|
+
this._url = await this.evaluate("location.href");
|
|
1174
|
+
} catch {
|
|
1175
|
+
}
|
|
1171
1176
|
}
|
|
1172
1177
|
async goForward(opts = {}) {
|
|
1173
1178
|
await this.evaluate("() => history.forward()");
|
|
1174
|
-
await this.waitForLoadState(opts.waitUntil ?? "
|
|
1179
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 5e3).catch(() => {
|
|
1180
|
+
});
|
|
1181
|
+
try {
|
|
1182
|
+
this._url = await this.evaluate("location.href");
|
|
1183
|
+
} catch {
|
|
1184
|
+
}
|
|
1175
1185
|
}
|
|
1176
1186
|
async reload(opts = {}) {
|
|
1177
1187
|
this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
|
|
@@ -1166,11 +1166,21 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1166
1166
|
}
|
|
1167
1167
|
async goBack(opts = {}) {
|
|
1168
1168
|
await this.evaluate("() => history.back()");
|
|
1169
|
-
await this.waitForLoadState(opts.waitUntil ?? "
|
|
1169
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 5e3).catch(() => {
|
|
1170
|
+
});
|
|
1171
|
+
try {
|
|
1172
|
+
this._url = await this.evaluate("location.href");
|
|
1173
|
+
} catch {
|
|
1174
|
+
}
|
|
1170
1175
|
}
|
|
1171
1176
|
async goForward(opts = {}) {
|
|
1172
1177
|
await this.evaluate("() => history.forward()");
|
|
1173
|
-
await this.waitForLoadState(opts.waitUntil ?? "
|
|
1178
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 5e3).catch(() => {
|
|
1179
|
+
});
|
|
1180
|
+
try {
|
|
1181
|
+
this._url = await this.evaluate("location.href");
|
|
1182
|
+
} catch {
|
|
1183
|
+
}
|
|
1174
1184
|
}
|
|
1175
1185
|
async reload(opts = {}) {
|
|
1176
1186
|
this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
|
|
@@ -1172,11 +1172,21 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1172
1172
|
}
|
|
1173
1173
|
async goBack(opts = {}) {
|
|
1174
1174
|
await this.evaluate("() => history.back()");
|
|
1175
|
-
await this.waitForLoadState(opts.waitUntil ?? "
|
|
1175
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 5e3).catch(() => {
|
|
1176
|
+
});
|
|
1177
|
+
try {
|
|
1178
|
+
this._url = await this.evaluate("location.href");
|
|
1179
|
+
} catch {
|
|
1180
|
+
}
|
|
1176
1181
|
}
|
|
1177
1182
|
async goForward(opts = {}) {
|
|
1178
1183
|
await this.evaluate("() => history.forward()");
|
|
1179
|
-
await this.waitForLoadState(opts.waitUntil ?? "
|
|
1184
|
+
await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 5e3).catch(() => {
|
|
1185
|
+
});
|
|
1186
|
+
try {
|
|
1187
|
+
this._url = await this.evaluate("location.href");
|
|
1188
|
+
} catch {
|
|
1189
|
+
}
|
|
1180
1190
|
}
|
|
1181
1191
|
async reload(opts = {}) {
|
|
1182
1192
|
this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
|
|
@@ -4264,21 +4274,27 @@ async function fetchNoProxy(url) {
|
|
|
4264
4274
|
}
|
|
4265
4275
|
async function resolveCDPEndpoint(raw) {
|
|
4266
4276
|
if (raw === "auto") {
|
|
4267
|
-
const
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4277
|
+
const ports = [9222, 9221, 9223, 9224];
|
|
4278
|
+
for (const port of ports) {
|
|
4279
|
+
try {
|
|
4280
|
+
const httpResp = await fetchNoProxy(`http://localhost:${port}/json/version`);
|
|
4281
|
+
if (httpResp.ok) {
|
|
4282
|
+
const data = await httpResp.json();
|
|
4283
|
+
if (data.webSocketDebuggerUrl) {
|
|
4284
|
+
return data.webSocketDebuggerUrl;
|
|
4285
|
+
}
|
|
4286
|
+
}
|
|
4287
|
+
} catch {
|
|
4288
|
+
}
|
|
4289
|
+
}
|
|
4290
|
+
throw new Error(
|
|
4291
|
+
`Could not auto-discover CDP endpoint. Tried ports: ${ports.join(", ")}.
|
|
4292
|
+
\u53EF\u80FD\u539F\u56E0\uFF1A\u6CA1\u6709 Chrome \u4EE5 --remote-debugging-port \u542F\u52A8\u3002
|
|
4271
4293
|
\u89E3\u51B3\u65B9\u6CD5\uFF1A
|
|
4272
|
-
1. \
|
|
4273
|
-
2. \
|
|
4294
|
+
1. \u542F\u52A8 Chrome: google-chrome --remote-debugging-port=9222
|
|
4295
|
+
2. \u6216\u7528 cdp-tunnel: npx cdp-tunnel setup
|
|
4274
4296
|
3. \u6216\u6307\u5B9A\u7AEF\u53E3: --cdp <port>`
|
|
4275
|
-
|
|
4276
|
-
}
|
|
4277
|
-
const data = await httpResp.json();
|
|
4278
|
-
if (!data.webSocketDebuggerUrl) {
|
|
4279
|
-
throw new Error("Could not auto-discover CDP endpoint from localhost:9222");
|
|
4280
|
-
}
|
|
4281
|
-
return data.webSocketDebuggerUrl;
|
|
4297
|
+
);
|
|
4282
4298
|
}
|
|
4283
4299
|
if (/^\d+$/.test(raw)) {
|
|
4284
4300
|
const port = raw;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
launch
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IDJ5NILK.js";
|
|
4
4
|
import {
|
|
5
5
|
errMsg
|
|
6
6
|
} from "./chunk-GDKLH7ZY.js";
|
|
@@ -1400,21 +1400,27 @@ async function fetchNoProxy(url) {
|
|
|
1400
1400
|
}
|
|
1401
1401
|
async function resolveCDPEndpoint(raw) {
|
|
1402
1402
|
if (raw === "auto") {
|
|
1403
|
-
const
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1403
|
+
const ports = [9222, 9221, 9223, 9224];
|
|
1404
|
+
for (const port of ports) {
|
|
1405
|
+
try {
|
|
1406
|
+
const httpResp = await fetchNoProxy(`http://localhost:${port}/json/version`);
|
|
1407
|
+
if (httpResp.ok) {
|
|
1408
|
+
const data = await httpResp.json();
|
|
1409
|
+
if (data.webSocketDebuggerUrl) {
|
|
1410
|
+
return data.webSocketDebuggerUrl;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
} catch {
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
throw new Error(
|
|
1417
|
+
`Could not auto-discover CDP endpoint. Tried ports: ${ports.join(", ")}.
|
|
1418
|
+
\u53EF\u80FD\u539F\u56E0\uFF1A\u6CA1\u6709 Chrome \u4EE5 --remote-debugging-port \u542F\u52A8\u3002
|
|
1407
1419
|
\u89E3\u51B3\u65B9\u6CD5\uFF1A
|
|
1408
|
-
1. \
|
|
1409
|
-
2. \
|
|
1420
|
+
1. \u542F\u52A8 Chrome: google-chrome --remote-debugging-port=9222
|
|
1421
|
+
2. \u6216\u7528 cdp-tunnel: npx cdp-tunnel setup
|
|
1410
1422
|
3. \u6216\u6307\u5B9A\u7AEF\u53E3: --cdp <port>`
|
|
1411
|
-
|
|
1412
|
-
}
|
|
1413
|
-
const data = await httpResp.json();
|
|
1414
|
-
if (!data.webSocketDebuggerUrl) {
|
|
1415
|
-
throw new Error("Could not auto-discover CDP endpoint from localhost:9222");
|
|
1416
|
-
}
|
|
1417
|
-
return data.webSocketDebuggerUrl;
|
|
1423
|
+
);
|
|
1418
1424
|
}
|
|
1419
1425
|
if (/^\d+$/.test(raw)) {
|
|
1420
1426
|
const port = raw;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
launch
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IDJ5NILK.js";
|
|
4
4
|
import {
|
|
5
5
|
errMsg
|
|
6
6
|
} from "./chunk-GDKLH7ZY.js";
|
|
@@ -35,21 +35,27 @@ async function fetchNoProxy(url) {
|
|
|
35
35
|
}
|
|
36
36
|
async function resolveCDPEndpoint(raw) {
|
|
37
37
|
if (raw === "auto") {
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
const ports = [9222, 9221, 9223, 9224];
|
|
39
|
+
for (const port of ports) {
|
|
40
|
+
try {
|
|
41
|
+
const httpResp = await fetchNoProxy(`http://localhost:${port}/json/version`);
|
|
42
|
+
if (httpResp.ok) {
|
|
43
|
+
const data = await httpResp.json();
|
|
44
|
+
if (data.webSocketDebuggerUrl) {
|
|
45
|
+
return data.webSocketDebuggerUrl;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
throw new Error(
|
|
52
|
+
`Could not auto-discover CDP endpoint. Tried ports: ${ports.join(", ")}.
|
|
53
|
+
\u53EF\u80FD\u539F\u56E0\uFF1A\u6CA1\u6709 Chrome \u4EE5 --remote-debugging-port \u542F\u52A8\u3002
|
|
42
54
|
\u89E3\u51B3\u65B9\u6CD5\uFF1A
|
|
43
|
-
1. \
|
|
44
|
-
2. \
|
|
55
|
+
1. \u542F\u52A8 Chrome: google-chrome --remote-debugging-port=9222
|
|
56
|
+
2. \u6216\u7528 cdp-tunnel: npx cdp-tunnel setup
|
|
45
57
|
3. \u6216\u6307\u5B9A\u7AEF\u53E3: --cdp <port>`
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
const data = await httpResp.json();
|
|
49
|
-
if (!data.webSocketDebuggerUrl) {
|
|
50
|
-
throw new Error("Could not auto-discover CDP endpoint from localhost:9222");
|
|
51
|
-
}
|
|
52
|
-
return data.webSocketDebuggerUrl;
|
|
58
|
+
);
|
|
53
59
|
}
|
|
54
60
|
if (/^\d+$/.test(raw)) {
|
|
55
61
|
const port = raw;
|
package/dist/cli.js
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
resolveLaunchOpts,
|
|
26
26
|
saveSessionDiskMeta,
|
|
27
27
|
setActivePage
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-NW3WE5JK.js";
|
|
29
29
|
import "./chunk-TNEN6VQ2.js";
|
|
30
30
|
import {
|
|
31
31
|
forwardCommandLog,
|
|
@@ -376,7 +376,8 @@ var backCommand = registerCommand({
|
|
|
376
376
|
result: z.object({ url: z.string() }),
|
|
377
377
|
handler: async (_p, ctx) => {
|
|
378
378
|
await ctx.page.goBack();
|
|
379
|
-
|
|
379
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url());
|
|
380
|
+
return ok({ url });
|
|
380
381
|
}
|
|
381
382
|
});
|
|
382
383
|
var forwardCommand = registerCommand({
|
|
@@ -386,7 +387,8 @@ var forwardCommand = registerCommand({
|
|
|
386
387
|
result: z.object({ url: z.string() }),
|
|
387
388
|
handler: async (_p, ctx) => {
|
|
388
389
|
await ctx.page.goForward();
|
|
389
|
-
|
|
390
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url());
|
|
391
|
+
return ok({ url });
|
|
390
392
|
}
|
|
391
393
|
});
|
|
392
394
|
var refreshCommand = registerCommand({
|
|
@@ -395,8 +397,13 @@ var refreshCommand = registerCommand({
|
|
|
395
397
|
scope: "page",
|
|
396
398
|
result: z.object({ url: z.string() }),
|
|
397
399
|
handler: async (_p, ctx) => {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
+
try {
|
|
401
|
+
await ctx.page.reload();
|
|
402
|
+
} catch (err) {
|
|
403
|
+
return fail(`Refresh failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
404
|
+
}
|
|
405
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url());
|
|
406
|
+
return ok({ url });
|
|
400
407
|
}
|
|
401
408
|
});
|
|
402
409
|
var titleCommand = registerCommand({
|
|
@@ -415,7 +422,8 @@ var urlCommand = registerCommand({
|
|
|
415
422
|
scope: "page",
|
|
416
423
|
result: z.object({ url: z.string() }),
|
|
417
424
|
handler: async (_p, ctx) => {
|
|
418
|
-
|
|
425
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url() || "about:blank");
|
|
426
|
+
return ok({ url });
|
|
419
427
|
}
|
|
420
428
|
});
|
|
421
429
|
registerCommand({
|
|
@@ -7075,7 +7083,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7075
7083
|
}
|
|
7076
7084
|
let targetPageOverride = null;
|
|
7077
7085
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7078
|
-
const { findTargetPage } = await import("./browser-
|
|
7086
|
+
const { findTargetPage } = await import("./browser-5CM4GUZU.js");
|
|
7079
7087
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7080
7088
|
if (!targetPageOverride) {
|
|
7081
7089
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -10026,6 +10034,12 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
10026
10034
|
};
|
|
10027
10035
|
break;
|
|
10028
10036
|
}
|
|
10037
|
+
case "waitForTimeout":
|
|
10038
|
+
cmdName = "waitForTimeout";
|
|
10039
|
+
params = {
|
|
10040
|
+
timeout: args[0] ? Number(args[0]) : options.timeout ? Number(options.timeout) : 1e3
|
|
10041
|
+
};
|
|
10042
|
+
break;
|
|
10029
10043
|
default:
|
|
10030
10044
|
cmdName = command;
|
|
10031
10045
|
params = { ...options };
|
|
@@ -11838,18 +11852,6 @@ function printChainResult(chainResult) {
|
|
|
11838
11852
|
console.error(`Stopped: ${chainResult.stoppedReason}`);
|
|
11839
11853
|
}
|
|
11840
11854
|
}
|
|
11841
|
-
function printChainResultBrief(chainResult) {
|
|
11842
|
-
for (const step of chainResult.steps) {
|
|
11843
|
-
if (step.success) {
|
|
11844
|
-
console.log(`[OK] ${step.raw}`);
|
|
11845
|
-
} else {
|
|
11846
|
-
console.error(`[FAIL] ${step.raw}: ${step.message}`);
|
|
11847
|
-
}
|
|
11848
|
-
}
|
|
11849
|
-
if (chainResult.stoppedReason) {
|
|
11850
|
-
console.error(`Stopped: ${chainResult.stoppedReason}`);
|
|
11851
|
-
}
|
|
11852
|
-
}
|
|
11853
11855
|
|
|
11854
11856
|
// src/server/http-server.ts
|
|
11855
11857
|
import { createServer } from "http";
|
|
@@ -12378,10 +12380,10 @@ function extractSessionNameFromArgv(argv) {
|
|
|
12378
12380
|
async function handleEvalMode(argv) {
|
|
12379
12381
|
const evalCommands = parseEvalFlags(argv);
|
|
12380
12382
|
if (evalCommands.length === 0) return;
|
|
12381
|
-
const chain = evalCommands.join("
|
|
12383
|
+
const chain = evalCommands.join(" ; ");
|
|
12382
12384
|
const cdpEndpoint = extractCdpFromArgv(argv);
|
|
12383
12385
|
const chainResult = await executeChain(chain, { cdpEndpoint });
|
|
12384
|
-
|
|
12386
|
+
printChainResult(chainResult);
|
|
12385
12387
|
if (!chainResult.success) throw new Error("Command failed");
|
|
12386
12388
|
}
|
|
12387
12389
|
async function handleChainInput(input, argv) {
|
|
@@ -12425,12 +12427,8 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12425
12427
|
const possibleCmd = argv[0].substring(0, spaceIdx);
|
|
12426
12428
|
if (/^[a-zA-Z][\w-]*$/.test(possibleCmd)) {
|
|
12427
12429
|
const remainder = argv[0].substring(spaceIdx + 1);
|
|
12428
|
-
|
|
12429
|
-
|
|
12430
|
-
argv = [possibleCmd, ...remainderParts, ...argv.slice(1)];
|
|
12431
|
-
} else {
|
|
12432
|
-
argv = [possibleCmd, remainder, ...argv.slice(1)];
|
|
12433
|
-
}
|
|
12430
|
+
const remainderParts = remainder.split(/\s+/).filter(Boolean);
|
|
12431
|
+
argv = [possibleCmd, ...remainderParts, ...argv.slice(1)];
|
|
12434
12432
|
}
|
|
12435
12433
|
}
|
|
12436
12434
|
} catch (e) {
|
|
@@ -12444,7 +12442,7 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12444
12442
|
const mode = options.json ? "json" : options.yaml ? "yaml" : "text";
|
|
12445
12443
|
const sessionName = options.session || process.env.XBROWSER_SESSION || "default";
|
|
12446
12444
|
const cdpEndpoint = options.cdp || process.env.XBROWSER_CDP;
|
|
12447
|
-
if (options.version
|
|
12445
|
+
if (options.version) {
|
|
12448
12446
|
console.log(`xbrowser v${version}`);
|
|
12449
12447
|
return;
|
|
12450
12448
|
}
|
|
@@ -13041,7 +13039,7 @@ async function main() {
|
|
|
13041
13039
|
const command = process.argv[2];
|
|
13042
13040
|
const isLongRunning = command === "preview" || command === "serve";
|
|
13043
13041
|
if (!isLongRunning) {
|
|
13044
|
-
const { ensureProcessCanExit } = await import("./browser-
|
|
13042
|
+
const { ensureProcessCanExit } = await import("./browser-5CM4GUZU.js");
|
|
13045
13043
|
await ensureProcessCanExit().catch(() => {
|
|
13046
13044
|
});
|
|
13047
13045
|
process.exit(exitCode);
|
package/dist/daemon-main.js
CHANGED
|
@@ -21,8 +21,8 @@ import {
|
|
|
21
21
|
resolveLaunchOpts,
|
|
22
22
|
saveSessionDiskMeta,
|
|
23
23
|
setActivePage
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-
|
|
24
|
+
} from "./chunk-SMRIC22G.js";
|
|
25
|
+
import "./chunk-IDJ5NILK.js";
|
|
26
26
|
import "./chunk-TNEN6VQ2.js";
|
|
27
27
|
import {
|
|
28
28
|
getPluginLoader
|
|
@@ -337,7 +337,8 @@ var backCommand = registerCommand({
|
|
|
337
337
|
result: z.object({ url: z.string() }),
|
|
338
338
|
handler: async (_p, ctx) => {
|
|
339
339
|
await ctx.page.goBack();
|
|
340
|
-
|
|
340
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url());
|
|
341
|
+
return ok({ url });
|
|
341
342
|
}
|
|
342
343
|
});
|
|
343
344
|
var forwardCommand = registerCommand({
|
|
@@ -347,7 +348,8 @@ var forwardCommand = registerCommand({
|
|
|
347
348
|
result: z.object({ url: z.string() }),
|
|
348
349
|
handler: async (_p, ctx) => {
|
|
349
350
|
await ctx.page.goForward();
|
|
350
|
-
|
|
351
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url());
|
|
352
|
+
return ok({ url });
|
|
351
353
|
}
|
|
352
354
|
});
|
|
353
355
|
var refreshCommand = registerCommand({
|
|
@@ -356,8 +358,13 @@ var refreshCommand = registerCommand({
|
|
|
356
358
|
scope: "page",
|
|
357
359
|
result: z.object({ url: z.string() }),
|
|
358
360
|
handler: async (_p, ctx) => {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
+
try {
|
|
362
|
+
await ctx.page.reload();
|
|
363
|
+
} catch (err) {
|
|
364
|
+
return fail(`Refresh failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
365
|
+
}
|
|
366
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url());
|
|
367
|
+
return ok({ url });
|
|
361
368
|
}
|
|
362
369
|
});
|
|
363
370
|
var titleCommand = registerCommand({
|
|
@@ -376,7 +383,8 @@ var urlCommand = registerCommand({
|
|
|
376
383
|
scope: "page",
|
|
377
384
|
result: z.object({ url: z.string() }),
|
|
378
385
|
handler: async (_p, ctx) => {
|
|
379
|
-
|
|
386
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url() || "about:blank");
|
|
387
|
+
return ok({ url });
|
|
380
388
|
}
|
|
381
389
|
});
|
|
382
390
|
registerCommand({
|
|
@@ -6606,7 +6614,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
6606
6614
|
}
|
|
6607
6615
|
let targetPageOverride = null;
|
|
6608
6616
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
6609
|
-
const { findTargetPage } = await import("./browser-
|
|
6617
|
+
const { findTargetPage } = await import("./browser-V3VHXQQF.js");
|
|
6610
6618
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
6611
6619
|
if (!targetPageOverride) {
|
|
6612
6620
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -8322,7 +8330,7 @@ function createRPCHandler() {
|
|
|
8322
8330
|
const isNewFormat = Array.isArray(parsed.actions);
|
|
8323
8331
|
if (isNewFormat) {
|
|
8324
8332
|
try {
|
|
8325
|
-
const { SessionReplayer } = await import("./session-replayer-
|
|
8333
|
+
const { SessionReplayer } = await import("./session-replayer-F4ORJMCL.js");
|
|
8326
8334
|
const replayer = new SessionReplayer({
|
|
8327
8335
|
page: session.page,
|
|
8328
8336
|
stepDelay: slowMo * 500,
|
package/dist/index.js
CHANGED
|
@@ -81,8 +81,8 @@ import {
|
|
|
81
81
|
resolveLaunchOpts,
|
|
82
82
|
saveSessionDiskMeta,
|
|
83
83
|
setActivePage
|
|
84
|
-
} from "./chunk-
|
|
85
|
-
import "./chunk-
|
|
84
|
+
} from "./chunk-Z6GGTJL5.js";
|
|
85
|
+
import "./chunk-IDJ5NILK.js";
|
|
86
86
|
import "./chunk-TNEN6VQ2.js";
|
|
87
87
|
import {
|
|
88
88
|
errMsg
|
|
@@ -416,7 +416,8 @@ var backCommand = registerCommand({
|
|
|
416
416
|
result: z.object({ url: z.string() }),
|
|
417
417
|
handler: async (_p, ctx) => {
|
|
418
418
|
await ctx.page.goBack();
|
|
419
|
-
|
|
419
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url());
|
|
420
|
+
return ok({ url });
|
|
420
421
|
}
|
|
421
422
|
});
|
|
422
423
|
var forwardCommand = registerCommand({
|
|
@@ -426,7 +427,8 @@ var forwardCommand = registerCommand({
|
|
|
426
427
|
result: z.object({ url: z.string() }),
|
|
427
428
|
handler: async (_p, ctx) => {
|
|
428
429
|
await ctx.page.goForward();
|
|
429
|
-
|
|
430
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url());
|
|
431
|
+
return ok({ url });
|
|
430
432
|
}
|
|
431
433
|
});
|
|
432
434
|
var refreshCommand = registerCommand({
|
|
@@ -435,8 +437,13 @@ var refreshCommand = registerCommand({
|
|
|
435
437
|
scope: "page",
|
|
436
438
|
result: z.object({ url: z.string() }),
|
|
437
439
|
handler: async (_p, ctx) => {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
+
try {
|
|
441
|
+
await ctx.page.reload();
|
|
442
|
+
} catch (err) {
|
|
443
|
+
return fail(`Refresh failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
444
|
+
}
|
|
445
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url());
|
|
446
|
+
return ok({ url });
|
|
440
447
|
}
|
|
441
448
|
});
|
|
442
449
|
var titleCommand = registerCommand({
|
|
@@ -455,7 +462,8 @@ var urlCommand = registerCommand({
|
|
|
455
462
|
scope: "page",
|
|
456
463
|
result: z.object({ url: z.string() }),
|
|
457
464
|
handler: async (_p, ctx) => {
|
|
458
|
-
|
|
465
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url() || "about:blank");
|
|
466
|
+
return ok({ url });
|
|
459
467
|
}
|
|
460
468
|
});
|
|
461
469
|
registerCommand({
|
|
@@ -7395,7 +7403,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7395
7403
|
}
|
|
7396
7404
|
let targetPageOverride = null;
|
|
7397
7405
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7398
|
-
const { findTargetPage } = await import("./browser-
|
|
7406
|
+
const { findTargetPage } = await import("./browser-2OALOLR2.js");
|
|
7399
7407
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7400
7408
|
if (!targetPageOverride) {
|
|
7401
7409
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -10366,6 +10374,12 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
10366
10374
|
};
|
|
10367
10375
|
break;
|
|
10368
10376
|
}
|
|
10377
|
+
case "waitForTimeout":
|
|
10378
|
+
cmdName = "waitForTimeout";
|
|
10379
|
+
params = {
|
|
10380
|
+
timeout: args[0] ? Number(args[0]) : options.timeout ? Number(options.timeout) : 1e3
|
|
10381
|
+
};
|
|
10382
|
+
break;
|
|
10369
10383
|
default:
|
|
10370
10384
|
cmdName = command;
|
|
10371
10385
|
params = { ...options };
|
|
@@ -12178,18 +12192,6 @@ function printChainResult(chainResult) {
|
|
|
12178
12192
|
console.error(`Stopped: ${chainResult.stoppedReason}`);
|
|
12179
12193
|
}
|
|
12180
12194
|
}
|
|
12181
|
-
function printChainResultBrief(chainResult) {
|
|
12182
|
-
for (const step of chainResult.steps) {
|
|
12183
|
-
if (step.success) {
|
|
12184
|
-
console.log(`[OK] ${step.raw}`);
|
|
12185
|
-
} else {
|
|
12186
|
-
console.error(`[FAIL] ${step.raw}: ${step.message}`);
|
|
12187
|
-
}
|
|
12188
|
-
}
|
|
12189
|
-
if (chainResult.stoppedReason) {
|
|
12190
|
-
console.error(`Stopped: ${chainResult.stoppedReason}`);
|
|
12191
|
-
}
|
|
12192
|
-
}
|
|
12193
12195
|
|
|
12194
12196
|
// src/server/http-server.ts
|
|
12195
12197
|
import { createServer } from "http";
|
|
@@ -12718,10 +12720,10 @@ function extractSessionNameFromArgv(argv) {
|
|
|
12718
12720
|
async function handleEvalMode(argv) {
|
|
12719
12721
|
const evalCommands = parseEvalFlags(argv);
|
|
12720
12722
|
if (evalCommands.length === 0) return;
|
|
12721
|
-
const chain = evalCommands.join("
|
|
12723
|
+
const chain = evalCommands.join(" ; ");
|
|
12722
12724
|
const cdpEndpoint = extractCdpFromArgv(argv);
|
|
12723
12725
|
const chainResult = await executeChain(chain, { cdpEndpoint });
|
|
12724
|
-
|
|
12726
|
+
printChainResult(chainResult);
|
|
12725
12727
|
if (!chainResult.success) throw new Error("Command failed");
|
|
12726
12728
|
}
|
|
12727
12729
|
async function handleChainInput(input, argv) {
|
|
@@ -12765,12 +12767,8 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12765
12767
|
const possibleCmd = argv[0].substring(0, spaceIdx);
|
|
12766
12768
|
if (/^[a-zA-Z][\w-]*$/.test(possibleCmd)) {
|
|
12767
12769
|
const remainder = argv[0].substring(spaceIdx + 1);
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
argv = [possibleCmd, ...remainderParts, ...argv.slice(1)];
|
|
12771
|
-
} else {
|
|
12772
|
-
argv = [possibleCmd, remainder, ...argv.slice(1)];
|
|
12773
|
-
}
|
|
12770
|
+
const remainderParts = remainder.split(/\s+/).filter(Boolean);
|
|
12771
|
+
argv = [possibleCmd, ...remainderParts, ...argv.slice(1)];
|
|
12774
12772
|
}
|
|
12775
12773
|
}
|
|
12776
12774
|
} catch (e) {
|
|
@@ -12784,7 +12782,7 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12784
12782
|
const mode = options.json ? "json" : options.yaml ? "yaml" : "text";
|
|
12785
12783
|
const sessionName = options.session || process.env.XBROWSER_SESSION || "default";
|
|
12786
12784
|
const cdpEndpoint = options.cdp || process.env.XBROWSER_CDP;
|
|
12787
|
-
if (options.version
|
|
12785
|
+
if (options.version) {
|
|
12788
12786
|
console.log(`xbrowser v${version}`);
|
|
12789
12787
|
return;
|
|
12790
12788
|
}
|
|
@@ -16168,7 +16166,7 @@ var DataCollector = class {
|
|
|
16168
16166
|
return results;
|
|
16169
16167
|
}
|
|
16170
16168
|
async createBrowserContext() {
|
|
16171
|
-
const { launch } = await import("./cdp-driver-
|
|
16169
|
+
const { launch } = await import("./cdp-driver-VRXHK6P6.js");
|
|
16172
16170
|
const { browser } = await launch({
|
|
16173
16171
|
headless: true,
|
|
16174
16172
|
args: ["--no-sandbox", "--disable-setuid-sandbox"]
|
|
@@ -31,7 +31,7 @@ var SessionReplayer = class {
|
|
|
31
31
|
if (this.opts.page) {
|
|
32
32
|
this.page = this.opts.page;
|
|
33
33
|
} else if (this.opts.cdpUrl) {
|
|
34
|
-
const { launch } = await import("./cdp-driver-
|
|
34
|
+
const { launch } = await import("./cdp-driver-VRXHK6P6.js");
|
|
35
35
|
const { browser } = await launch({ cdpEndpoint: this.opts.cdpUrl });
|
|
36
36
|
let contexts = browser.contexts();
|
|
37
37
|
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.4.
|
|
3
|
+
"version": "1.4.5",
|
|
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": {
|