@xbrowser/cli 1.4.4 → 1.4.6
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-YKJO3BOQ.js → browser-2OK26HBS.js} +2 -2
- package/dist/{browser-DS24BWJW.js → browser-SOML2EWR.js} +1 -1
- package/dist/{browser-KBUORWR3.js → browser-ZTTS2SVT.js} +2 -2
- package/dist/{cdp-driver-ACRHJMS3.js → cdp-driver-67B5EI4C.js} +8 -14
- package/dist/{cdp-driver-VRXHK6P6.js → cdp-driver-UGO45HXR.js} +1 -1
- package/dist/{chunk-IDJ5NILK.js → chunk-2RHJEYWU.js} +8 -14
- package/dist/{chunk-X3FKWJV4.js → chunk-LYVU6SD3.js} +20 -14
- package/dist/{chunk-4W54GEMV.js → chunk-NQSFETTQ.js} +20 -14
- package/dist/{chunk-CFPPWKVO.js → chunk-RGS6ECTH.js} +27 -27
- package/dist/cli.js +37 -29
- package/dist/daemon-main.js +16 -10
- package/dist/index.js +38 -30
- package/dist/{session-replayer-F4ORJMCL.js → session-replayer-YIGRIIDD.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-NQSFETTQ.js";
|
|
24
|
+
import "./chunk-2RHJEYWU.js";
|
|
25
25
|
import "./chunk-TNEN6VQ2.js";
|
|
26
26
|
import "./chunk-GDKLH7ZY.js";
|
|
27
27
|
import "./chunk-KFQGP6VL.js";
|
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-LYVU6SD3.js";
|
|
24
|
+
import "./chunk-2RHJEYWU.js";
|
|
25
25
|
import "./chunk-TNEN6VQ2.js";
|
|
26
26
|
import "./chunk-GDKLH7ZY.js";
|
|
27
27
|
import "./chunk-ABXMBNQ6.js";
|
|
@@ -1165,23 +1165,17 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1165
1165
|
headers: () => headers
|
|
1166
1166
|
};
|
|
1167
1167
|
}
|
|
1168
|
-
async goBack(
|
|
1168
|
+
async goBack(_opts = {}) {
|
|
1169
|
+
const prevUrl = await this.evaluate("location.href").catch(() => "");
|
|
1169
1170
|
await this.evaluate("() => history.back()");
|
|
1170
|
-
await this.
|
|
1171
|
-
|
|
1172
|
-
try {
|
|
1173
|
-
this._url = await this.evaluate("location.href");
|
|
1174
|
-
} catch {
|
|
1175
|
-
}
|
|
1171
|
+
await this.waitForTimeout(2e3);
|
|
1172
|
+
this._url = await this.evaluate("location.href").catch(() => prevUrl);
|
|
1176
1173
|
}
|
|
1177
|
-
async goForward(
|
|
1174
|
+
async goForward(_opts = {}) {
|
|
1175
|
+
const prevUrl = await this.evaluate("location.href").catch(() => "");
|
|
1178
1176
|
await this.evaluate("() => history.forward()");
|
|
1179
|
-
await this.
|
|
1180
|
-
|
|
1181
|
-
try {
|
|
1182
|
-
this._url = await this.evaluate("location.href");
|
|
1183
|
-
} catch {
|
|
1184
|
-
}
|
|
1177
|
+
await this.waitForTimeout(2e3);
|
|
1178
|
+
this._url = await this.evaluate("location.href").catch(() => prevUrl);
|
|
1185
1179
|
}
|
|
1186
1180
|
async reload(opts = {}) {
|
|
1187
1181
|
this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
|
|
@@ -1164,23 +1164,17 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1164
1164
|
headers: () => headers
|
|
1165
1165
|
};
|
|
1166
1166
|
}
|
|
1167
|
-
async goBack(
|
|
1167
|
+
async goBack(_opts = {}) {
|
|
1168
|
+
const prevUrl = await this.evaluate("location.href").catch(() => "");
|
|
1168
1169
|
await this.evaluate("() => history.back()");
|
|
1169
|
-
await this.
|
|
1170
|
-
|
|
1171
|
-
try {
|
|
1172
|
-
this._url = await this.evaluate("location.href");
|
|
1173
|
-
} catch {
|
|
1174
|
-
}
|
|
1170
|
+
await this.waitForTimeout(2e3);
|
|
1171
|
+
this._url = await this.evaluate("location.href").catch(() => prevUrl);
|
|
1175
1172
|
}
|
|
1176
|
-
async goForward(
|
|
1173
|
+
async goForward(_opts = {}) {
|
|
1174
|
+
const prevUrl = await this.evaluate("location.href").catch(() => "");
|
|
1177
1175
|
await this.evaluate("() => history.forward()");
|
|
1178
|
-
await this.
|
|
1179
|
-
|
|
1180
|
-
try {
|
|
1181
|
-
this._url = await this.evaluate("location.href");
|
|
1182
|
-
} catch {
|
|
1183
|
-
}
|
|
1176
|
+
await this.waitForTimeout(2e3);
|
|
1177
|
+
this._url = await this.evaluate("location.href").catch(() => prevUrl);
|
|
1184
1178
|
}
|
|
1185
1179
|
async reload(opts = {}) {
|
|
1186
1180
|
this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
launch
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2RHJEYWU.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;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
launch
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2RHJEYWU.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;
|
|
@@ -1170,23 +1170,17 @@ var XBPageImpl = class _XBPageImpl {
|
|
|
1170
1170
|
headers: () => headers
|
|
1171
1171
|
};
|
|
1172
1172
|
}
|
|
1173
|
-
async goBack(
|
|
1173
|
+
async goBack(_opts = {}) {
|
|
1174
|
+
const prevUrl = await this.evaluate("location.href").catch(() => "");
|
|
1174
1175
|
await this.evaluate("() => history.back()");
|
|
1175
|
-
await this.
|
|
1176
|
-
|
|
1177
|
-
try {
|
|
1178
|
-
this._url = await this.evaluate("location.href");
|
|
1179
|
-
} catch {
|
|
1180
|
-
}
|
|
1176
|
+
await this.waitForTimeout(2e3);
|
|
1177
|
+
this._url = await this.evaluate("location.href").catch(() => prevUrl);
|
|
1181
1178
|
}
|
|
1182
|
-
async goForward(
|
|
1179
|
+
async goForward(_opts = {}) {
|
|
1180
|
+
const prevUrl = await this.evaluate("location.href").catch(() => "");
|
|
1183
1181
|
await this.evaluate("() => history.forward()");
|
|
1184
|
-
await this.
|
|
1185
|
-
|
|
1186
|
-
try {
|
|
1187
|
-
this._url = await this.evaluate("location.href");
|
|
1188
|
-
} catch {
|
|
1189
|
-
}
|
|
1182
|
+
await this.waitForTimeout(2e3);
|
|
1183
|
+
this._url = await this.evaluate("location.href").catch(() => prevUrl);
|
|
1190
1184
|
}
|
|
1191
1185
|
async reload(opts = {}) {
|
|
1192
1186
|
this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
|
|
@@ -4274,21 +4268,27 @@ async function fetchNoProxy(url) {
|
|
|
4274
4268
|
}
|
|
4275
4269
|
async function resolveCDPEndpoint(raw) {
|
|
4276
4270
|
if (raw === "auto") {
|
|
4277
|
-
const
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4271
|
+
const ports = [9222, 9221, 9223, 9224];
|
|
4272
|
+
for (const port of ports) {
|
|
4273
|
+
try {
|
|
4274
|
+
const httpResp = await fetchNoProxy(`http://localhost:${port}/json/version`);
|
|
4275
|
+
if (httpResp.ok) {
|
|
4276
|
+
const data = await httpResp.json();
|
|
4277
|
+
if (data.webSocketDebuggerUrl) {
|
|
4278
|
+
return data.webSocketDebuggerUrl;
|
|
4279
|
+
}
|
|
4280
|
+
}
|
|
4281
|
+
} catch {
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
throw new Error(
|
|
4285
|
+
`Could not auto-discover CDP endpoint. Tried ports: ${ports.join(", ")}.
|
|
4286
|
+
\u53EF\u80FD\u539F\u56E0\uFF1A\u6CA1\u6709 Chrome \u4EE5 --remote-debugging-port \u542F\u52A8\u3002
|
|
4281
4287
|
\u89E3\u51B3\u65B9\u6CD5\uFF1A
|
|
4282
|
-
1. \
|
|
4283
|
-
2. \
|
|
4288
|
+
1. \u542F\u52A8 Chrome: google-chrome --remote-debugging-port=9222
|
|
4289
|
+
2. \u6216\u7528 cdp-tunnel: npx cdp-tunnel setup
|
|
4284
4290
|
3. \u6216\u6307\u5B9A\u7AEF\u53E3: --cdp <port>`
|
|
4285
|
-
|
|
4286
|
-
}
|
|
4287
|
-
const data = await httpResp.json();
|
|
4288
|
-
if (!data.webSocketDebuggerUrl) {
|
|
4289
|
-
throw new Error("Could not auto-discover CDP endpoint from localhost:9222");
|
|
4290
|
-
}
|
|
4291
|
-
return data.webSocketDebuggerUrl;
|
|
4291
|
+
);
|
|
4292
4292
|
}
|
|
4293
4293
|
if (/^\d+$/.test(raw)) {
|
|
4294
4294
|
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-RGS6ECTH.js";
|
|
29
29
|
import "./chunk-TNEN6VQ2.js";
|
|
30
30
|
import {
|
|
31
31
|
forwardCommandLog,
|
|
@@ -397,8 +397,13 @@ var refreshCommand = registerCommand({
|
|
|
397
397
|
scope: "page",
|
|
398
398
|
result: z.object({ url: z.string() }),
|
|
399
399
|
handler: async (_p, ctx) => {
|
|
400
|
-
|
|
401
|
-
|
|
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 });
|
|
402
407
|
}
|
|
403
408
|
});
|
|
404
409
|
var titleCommand = registerCommand({
|
|
@@ -417,7 +422,8 @@ var urlCommand = registerCommand({
|
|
|
417
422
|
scope: "page",
|
|
418
423
|
result: z.object({ url: z.string() }),
|
|
419
424
|
handler: async (_p, ctx) => {
|
|
420
|
-
|
|
425
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url() || "about:blank");
|
|
426
|
+
return ok({ url });
|
|
421
427
|
}
|
|
422
428
|
});
|
|
423
429
|
registerCommand({
|
|
@@ -5460,12 +5466,12 @@ registerCommandDefinition("health", []);
|
|
|
5460
5466
|
registerCommandDefinition("scrape", ["url"]);
|
|
5461
5467
|
registerCommandDefinition("structure", []);
|
|
5462
5468
|
registerCommandDefinition("get-cookies", []);
|
|
5463
|
-
registerCommandDefinition("set-cookie", []);
|
|
5469
|
+
registerCommandDefinition("set-cookie", ["name", "value"]);
|
|
5464
5470
|
registerCommandDefinition("clear-cookies", []);
|
|
5465
5471
|
registerCommandDefinition("get-local-storage", []);
|
|
5466
|
-
registerCommandDefinition("set-local-storage", []);
|
|
5472
|
+
registerCommandDefinition("set-local-storage", ["key", "value"]);
|
|
5467
5473
|
registerCommandDefinition("clear-local-storage", []);
|
|
5468
|
-
registerCommandDefinition("set-viewport", []);
|
|
5474
|
+
registerCommandDefinition("set-viewport", ["width", "height"]);
|
|
5469
5475
|
registerCommandDefinition("frames", []);
|
|
5470
5476
|
registerCommandDefinition("frame", ["selector"]);
|
|
5471
5477
|
registerCommandDefinition("actions", ["url"]);
|
|
@@ -7077,7 +7083,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7077
7083
|
}
|
|
7078
7084
|
let targetPageOverride = null;
|
|
7079
7085
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7080
|
-
const { findTargetPage } = await import("./browser-
|
|
7086
|
+
const { findTargetPage } = await import("./browser-SOML2EWR.js");
|
|
7081
7087
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7082
7088
|
if (!targetPageOverride) {
|
|
7083
7089
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -10034,6 +10040,24 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
10034
10040
|
timeout: args[0] ? Number(args[0]) : options.timeout ? Number(options.timeout) : 1e3
|
|
10035
10041
|
};
|
|
10036
10042
|
break;
|
|
10043
|
+
case "set-cookie":
|
|
10044
|
+
cmdName = "set-cookie";
|
|
10045
|
+
params = {
|
|
10046
|
+
name: options.name || args[0],
|
|
10047
|
+
value: (options.value || options.v) ?? args[1],
|
|
10048
|
+
domain: options.domain,
|
|
10049
|
+
path: options.path,
|
|
10050
|
+
httpOnly: options.httpOnly ? Boolean(options.httpOnly) : void 0,
|
|
10051
|
+
secure: options.secure ? Boolean(options.secure) : void 0
|
|
10052
|
+
};
|
|
10053
|
+
break;
|
|
10054
|
+
case "set-local-storage":
|
|
10055
|
+
cmdName = "set-local-storage";
|
|
10056
|
+
params = {
|
|
10057
|
+
key: options.key || args[0],
|
|
10058
|
+
value: (options.value || options.v) ?? args[1]
|
|
10059
|
+
};
|
|
10060
|
+
break;
|
|
10037
10061
|
default:
|
|
10038
10062
|
cmdName = command;
|
|
10039
10063
|
params = { ...options };
|
|
@@ -11846,18 +11870,6 @@ function printChainResult(chainResult) {
|
|
|
11846
11870
|
console.error(`Stopped: ${chainResult.stoppedReason}`);
|
|
11847
11871
|
}
|
|
11848
11872
|
}
|
|
11849
|
-
function printChainResultBrief(chainResult) {
|
|
11850
|
-
for (const step of chainResult.steps) {
|
|
11851
|
-
if (step.success) {
|
|
11852
|
-
console.log(`[OK] ${step.raw}`);
|
|
11853
|
-
} else {
|
|
11854
|
-
console.error(`[FAIL] ${step.raw}: ${step.message}`);
|
|
11855
|
-
}
|
|
11856
|
-
}
|
|
11857
|
-
if (chainResult.stoppedReason) {
|
|
11858
|
-
console.error(`Stopped: ${chainResult.stoppedReason}`);
|
|
11859
|
-
}
|
|
11860
|
-
}
|
|
11861
11873
|
|
|
11862
11874
|
// src/server/http-server.ts
|
|
11863
11875
|
import { createServer } from "http";
|
|
@@ -12386,10 +12398,10 @@ function extractSessionNameFromArgv(argv) {
|
|
|
12386
12398
|
async function handleEvalMode(argv) {
|
|
12387
12399
|
const evalCommands = parseEvalFlags(argv);
|
|
12388
12400
|
if (evalCommands.length === 0) return;
|
|
12389
|
-
const chain = evalCommands.join("
|
|
12401
|
+
const chain = evalCommands.join(" ; ");
|
|
12390
12402
|
const cdpEndpoint = extractCdpFromArgv(argv);
|
|
12391
12403
|
const chainResult = await executeChain(chain, { cdpEndpoint });
|
|
12392
|
-
|
|
12404
|
+
printChainResult(chainResult);
|
|
12393
12405
|
if (!chainResult.success) throw new Error("Command failed");
|
|
12394
12406
|
}
|
|
12395
12407
|
async function handleChainInput(input, argv) {
|
|
@@ -12433,12 +12445,8 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12433
12445
|
const possibleCmd = argv[0].substring(0, spaceIdx);
|
|
12434
12446
|
if (/^[a-zA-Z][\w-]*$/.test(possibleCmd)) {
|
|
12435
12447
|
const remainder = argv[0].substring(spaceIdx + 1);
|
|
12436
|
-
|
|
12437
|
-
|
|
12438
|
-
argv = [possibleCmd, ...remainderParts, ...argv.slice(1)];
|
|
12439
|
-
} else {
|
|
12440
|
-
argv = [possibleCmd, remainder, ...argv.slice(1)];
|
|
12441
|
-
}
|
|
12448
|
+
const remainderParts = remainder.split(/\s+/).filter(Boolean);
|
|
12449
|
+
argv = [possibleCmd, ...remainderParts, ...argv.slice(1)];
|
|
12442
12450
|
}
|
|
12443
12451
|
}
|
|
12444
12452
|
} catch (e) {
|
|
@@ -13049,7 +13057,7 @@ async function main() {
|
|
|
13049
13057
|
const command = process.argv[2];
|
|
13050
13058
|
const isLongRunning = command === "preview" || command === "serve";
|
|
13051
13059
|
if (!isLongRunning) {
|
|
13052
|
-
const { ensureProcessCanExit } = await import("./browser-
|
|
13060
|
+
const { ensureProcessCanExit } = await import("./browser-SOML2EWR.js");
|
|
13053
13061
|
await ensureProcessCanExit().catch(() => {
|
|
13054
13062
|
});
|
|
13055
13063
|
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-NQSFETTQ.js";
|
|
25
|
+
import "./chunk-2RHJEYWU.js";
|
|
26
26
|
import "./chunk-TNEN6VQ2.js";
|
|
27
27
|
import {
|
|
28
28
|
getPluginLoader
|
|
@@ -358,8 +358,13 @@ var refreshCommand = registerCommand({
|
|
|
358
358
|
scope: "page",
|
|
359
359
|
result: z.object({ url: z.string() }),
|
|
360
360
|
handler: async (_p, ctx) => {
|
|
361
|
-
|
|
362
|
-
|
|
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 });
|
|
363
368
|
}
|
|
364
369
|
});
|
|
365
370
|
var titleCommand = registerCommand({
|
|
@@ -378,7 +383,8 @@ var urlCommand = registerCommand({
|
|
|
378
383
|
scope: "page",
|
|
379
384
|
result: z.object({ url: z.string() }),
|
|
380
385
|
handler: async (_p, ctx) => {
|
|
381
|
-
|
|
386
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url() || "about:blank");
|
|
387
|
+
return ok({ url });
|
|
382
388
|
}
|
|
383
389
|
});
|
|
384
390
|
registerCommand({
|
|
@@ -5421,12 +5427,12 @@ registerCommandDefinition("health", []);
|
|
|
5421
5427
|
registerCommandDefinition("scrape", ["url"]);
|
|
5422
5428
|
registerCommandDefinition("structure", []);
|
|
5423
5429
|
registerCommandDefinition("get-cookies", []);
|
|
5424
|
-
registerCommandDefinition("set-cookie", []);
|
|
5430
|
+
registerCommandDefinition("set-cookie", ["name", "value"]);
|
|
5425
5431
|
registerCommandDefinition("clear-cookies", []);
|
|
5426
5432
|
registerCommandDefinition("get-local-storage", []);
|
|
5427
|
-
registerCommandDefinition("set-local-storage", []);
|
|
5433
|
+
registerCommandDefinition("set-local-storage", ["key", "value"]);
|
|
5428
5434
|
registerCommandDefinition("clear-local-storage", []);
|
|
5429
|
-
registerCommandDefinition("set-viewport", []);
|
|
5435
|
+
registerCommandDefinition("set-viewport", ["width", "height"]);
|
|
5430
5436
|
registerCommandDefinition("frames", []);
|
|
5431
5437
|
registerCommandDefinition("frame", ["selector"]);
|
|
5432
5438
|
registerCommandDefinition("actions", ["url"]);
|
|
@@ -6608,7 +6614,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
6608
6614
|
}
|
|
6609
6615
|
let targetPageOverride = null;
|
|
6610
6616
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
6611
|
-
const { findTargetPage } = await import("./browser-
|
|
6617
|
+
const { findTargetPage } = await import("./browser-2OK26HBS.js");
|
|
6612
6618
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
6613
6619
|
if (!targetPageOverride) {
|
|
6614
6620
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -8324,7 +8330,7 @@ function createRPCHandler() {
|
|
|
8324
8330
|
const isNewFormat = Array.isArray(parsed.actions);
|
|
8325
8331
|
if (isNewFormat) {
|
|
8326
8332
|
try {
|
|
8327
|
-
const { SessionReplayer } = await import("./session-replayer-
|
|
8333
|
+
const { SessionReplayer } = await import("./session-replayer-YIGRIIDD.js");
|
|
8328
8334
|
const replayer = new SessionReplayer({
|
|
8329
8335
|
page: session.page,
|
|
8330
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-LYVU6SD3.js";
|
|
85
|
+
import "./chunk-2RHJEYWU.js";
|
|
86
86
|
import "./chunk-TNEN6VQ2.js";
|
|
87
87
|
import {
|
|
88
88
|
errMsg
|
|
@@ -437,8 +437,13 @@ var refreshCommand = registerCommand({
|
|
|
437
437
|
scope: "page",
|
|
438
438
|
result: z.object({ url: z.string() }),
|
|
439
439
|
handler: async (_p, ctx) => {
|
|
440
|
-
|
|
441
|
-
|
|
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 });
|
|
442
447
|
}
|
|
443
448
|
});
|
|
444
449
|
var titleCommand = registerCommand({
|
|
@@ -457,7 +462,8 @@ var urlCommand = registerCommand({
|
|
|
457
462
|
scope: "page",
|
|
458
463
|
result: z.object({ url: z.string() }),
|
|
459
464
|
handler: async (_p, ctx) => {
|
|
460
|
-
|
|
465
|
+
const url = await ctx.page.evaluate("location.href").catch(() => ctx.page.url() || "about:blank");
|
|
466
|
+
return ok({ url });
|
|
461
467
|
}
|
|
462
468
|
});
|
|
463
469
|
registerCommand({
|
|
@@ -5777,12 +5783,12 @@ registerCommandDefinition("health", []);
|
|
|
5777
5783
|
registerCommandDefinition("scrape", ["url"]);
|
|
5778
5784
|
registerCommandDefinition("structure", []);
|
|
5779
5785
|
registerCommandDefinition("get-cookies", []);
|
|
5780
|
-
registerCommandDefinition("set-cookie", []);
|
|
5786
|
+
registerCommandDefinition("set-cookie", ["name", "value"]);
|
|
5781
5787
|
registerCommandDefinition("clear-cookies", []);
|
|
5782
5788
|
registerCommandDefinition("get-local-storage", []);
|
|
5783
|
-
registerCommandDefinition("set-local-storage", []);
|
|
5789
|
+
registerCommandDefinition("set-local-storage", ["key", "value"]);
|
|
5784
5790
|
registerCommandDefinition("clear-local-storage", []);
|
|
5785
|
-
registerCommandDefinition("set-viewport", []);
|
|
5791
|
+
registerCommandDefinition("set-viewport", ["width", "height"]);
|
|
5786
5792
|
registerCommandDefinition("frames", []);
|
|
5787
5793
|
registerCommandDefinition("frame", ["selector"]);
|
|
5788
5794
|
registerCommandDefinition("actions", ["url"]);
|
|
@@ -7397,7 +7403,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7397
7403
|
}
|
|
7398
7404
|
let targetPageOverride = null;
|
|
7399
7405
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7400
|
-
const { findTargetPage } = await import("./browser-
|
|
7406
|
+
const { findTargetPage } = await import("./browser-ZTTS2SVT.js");
|
|
7401
7407
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7402
7408
|
if (!targetPageOverride) {
|
|
7403
7409
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -10374,6 +10380,24 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
10374
10380
|
timeout: args[0] ? Number(args[0]) : options.timeout ? Number(options.timeout) : 1e3
|
|
10375
10381
|
};
|
|
10376
10382
|
break;
|
|
10383
|
+
case "set-cookie":
|
|
10384
|
+
cmdName = "set-cookie";
|
|
10385
|
+
params = {
|
|
10386
|
+
name: options.name || args[0],
|
|
10387
|
+
value: (options.value || options.v) ?? args[1],
|
|
10388
|
+
domain: options.domain,
|
|
10389
|
+
path: options.path,
|
|
10390
|
+
httpOnly: options.httpOnly ? Boolean(options.httpOnly) : void 0,
|
|
10391
|
+
secure: options.secure ? Boolean(options.secure) : void 0
|
|
10392
|
+
};
|
|
10393
|
+
break;
|
|
10394
|
+
case "set-local-storage":
|
|
10395
|
+
cmdName = "set-local-storage";
|
|
10396
|
+
params = {
|
|
10397
|
+
key: options.key || args[0],
|
|
10398
|
+
value: (options.value || options.v) ?? args[1]
|
|
10399
|
+
};
|
|
10400
|
+
break;
|
|
10377
10401
|
default:
|
|
10378
10402
|
cmdName = command;
|
|
10379
10403
|
params = { ...options };
|
|
@@ -12186,18 +12210,6 @@ function printChainResult(chainResult) {
|
|
|
12186
12210
|
console.error(`Stopped: ${chainResult.stoppedReason}`);
|
|
12187
12211
|
}
|
|
12188
12212
|
}
|
|
12189
|
-
function printChainResultBrief(chainResult) {
|
|
12190
|
-
for (const step of chainResult.steps) {
|
|
12191
|
-
if (step.success) {
|
|
12192
|
-
console.log(`[OK] ${step.raw}`);
|
|
12193
|
-
} else {
|
|
12194
|
-
console.error(`[FAIL] ${step.raw}: ${step.message}`);
|
|
12195
|
-
}
|
|
12196
|
-
}
|
|
12197
|
-
if (chainResult.stoppedReason) {
|
|
12198
|
-
console.error(`Stopped: ${chainResult.stoppedReason}`);
|
|
12199
|
-
}
|
|
12200
|
-
}
|
|
12201
12213
|
|
|
12202
12214
|
// src/server/http-server.ts
|
|
12203
12215
|
import { createServer } from "http";
|
|
@@ -12726,10 +12738,10 @@ function extractSessionNameFromArgv(argv) {
|
|
|
12726
12738
|
async function handleEvalMode(argv) {
|
|
12727
12739
|
const evalCommands = parseEvalFlags(argv);
|
|
12728
12740
|
if (evalCommands.length === 0) return;
|
|
12729
|
-
const chain = evalCommands.join("
|
|
12741
|
+
const chain = evalCommands.join(" ; ");
|
|
12730
12742
|
const cdpEndpoint = extractCdpFromArgv(argv);
|
|
12731
12743
|
const chainResult = await executeChain(chain, { cdpEndpoint });
|
|
12732
|
-
|
|
12744
|
+
printChainResult(chainResult);
|
|
12733
12745
|
if (!chainResult.success) throw new Error("Command failed");
|
|
12734
12746
|
}
|
|
12735
12747
|
async function handleChainInput(input, argv) {
|
|
@@ -12773,12 +12785,8 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12773
12785
|
const possibleCmd = argv[0].substring(0, spaceIdx);
|
|
12774
12786
|
if (/^[a-zA-Z][\w-]*$/.test(possibleCmd)) {
|
|
12775
12787
|
const remainder = argv[0].substring(spaceIdx + 1);
|
|
12776
|
-
|
|
12777
|
-
|
|
12778
|
-
argv = [possibleCmd, ...remainderParts, ...argv.slice(1)];
|
|
12779
|
-
} else {
|
|
12780
|
-
argv = [possibleCmd, remainder, ...argv.slice(1)];
|
|
12781
|
-
}
|
|
12788
|
+
const remainderParts = remainder.split(/\s+/).filter(Boolean);
|
|
12789
|
+
argv = [possibleCmd, ...remainderParts, ...argv.slice(1)];
|
|
12782
12790
|
}
|
|
12783
12791
|
}
|
|
12784
12792
|
} catch (e) {
|
|
@@ -16176,7 +16184,7 @@ var DataCollector = class {
|
|
|
16176
16184
|
return results;
|
|
16177
16185
|
}
|
|
16178
16186
|
async createBrowserContext() {
|
|
16179
|
-
const { launch } = await import("./cdp-driver-
|
|
16187
|
+
const { launch } = await import("./cdp-driver-UGO45HXR.js");
|
|
16180
16188
|
const { browser } = await launch({
|
|
16181
16189
|
headless: true,
|
|
16182
16190
|
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-UGO45HXR.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.6",
|
|
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": {
|