@xbrowser/cli 1.3.0 → 1.4.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-CWI6BXYK.js → browser-ALV2PLW4.js} +2 -2
- package/dist/{browser-PZX7PO23.js → browser-VKZVOOVV.js} +1 -1
- package/dist/{browser-JP2LFPR2.js → browser-WMQRPYXX.js} +2 -2
- package/dist/{cdp-driver-S5STYUZZ.js → cdp-driver-72HOBP4C.js} +1 -1
- package/dist/{cdp-driver-RPUNQBGM.js → cdp-driver-JZPU5YXY.js} +49 -1
- package/dist/{chunk-SLQR57XZ.js → chunk-7OGKQWXE.js} +1 -1
- package/dist/{chunk-AT4PHAJY.js → chunk-GJAV3QGG.js} +2 -2
- package/dist/{chunk-L53IDAWK.js → chunk-MJFYLKGL.js} +3 -2
- package/dist/{chunk-QFROODUU.js → chunk-N4PIGZDG.js} +49 -1
- package/dist/{chunk-MNFOCOL6.js → chunk-TLOHV3FP.js} +49 -1
- package/dist/{chunk-6V57JME6.js → chunk-UZQYMXR5.js} +1 -1
- package/dist/cli.js +91 -44
- package/dist/daemon-main.js +65 -40
- package/dist/{extract-BSYBM4MR.js → extract-O46CC533.js} +3 -2
- package/dist/{extract-2ZFW2MX7.js → extract-RM62AJXW.js} +1 -1
- package/dist/{filter-3JQWBM5F.js → filter-K6FGRJQU.js} +1 -1
- package/dist/{filter-EDTFGLS5.js → filter-TAAYMSYI.js} +2 -2
- package/dist/index.js +94 -47
- package/dist/{session-replayer-IXLSCF5U.js → session-replayer-JIVFXVUL.js} +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -49,11 +49,11 @@ import {
|
|
|
49
49
|
extractAndSave,
|
|
50
50
|
extractRecording,
|
|
51
51
|
printExtractSummary
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-MJFYLKGL.js";
|
|
53
53
|
import {
|
|
54
54
|
filterRecording,
|
|
55
55
|
parseExcludeTypes
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-GJAV3QGG.js";
|
|
57
57
|
import {
|
|
58
58
|
SessionRecorder
|
|
59
59
|
} from "./chunk-ACFE6PKF.js";
|
|
@@ -81,8 +81,8 @@ import {
|
|
|
81
81
|
resolveLaunchOpts,
|
|
82
82
|
saveSessionDiskMeta,
|
|
83
83
|
setActivePage
|
|
84
|
-
} from "./chunk-
|
|
85
|
-
import "./chunk-
|
|
84
|
+
} from "./chunk-UZQYMXR5.js";
|
|
85
|
+
import "./chunk-N4PIGZDG.js";
|
|
86
86
|
import "./chunk-TNEN6VQ2.js";
|
|
87
87
|
import {
|
|
88
88
|
errMsg
|
|
@@ -114,7 +114,7 @@ var version = pkg.version;
|
|
|
114
114
|
// src/executor.ts
|
|
115
115
|
import {
|
|
116
116
|
ok as ok25,
|
|
117
|
-
fail as
|
|
117
|
+
fail as fail8,
|
|
118
118
|
isCommandResult,
|
|
119
119
|
CompositeStorage as CompositeStorage2,
|
|
120
120
|
TipCollector as TipCollector2,
|
|
@@ -300,7 +300,7 @@ function createStubContext(pluginName) {
|
|
|
300
300
|
|
|
301
301
|
// src/commands/navigation.ts
|
|
302
302
|
import { z } from "zod";
|
|
303
|
-
import { ok } from "@dyyz1993/xcli-core";
|
|
303
|
+
import { ok, fail } from "@dyyz1993/xcli-core";
|
|
304
304
|
|
|
305
305
|
// src/commands/command-registry.ts
|
|
306
306
|
var registry = /* @__PURE__ */ new Map();
|
|
@@ -392,13 +392,19 @@ var gotoCommand = registerCommand({
|
|
|
392
392
|
if (/^[\w-]+(\.[\w-]+)+/.test(url) || url.startsWith("localhost")) {
|
|
393
393
|
url = "https://" + url;
|
|
394
394
|
} else {
|
|
395
|
-
|
|
395
|
+
return fail(`Invalid URL: "${url}". Expected http(s)://, file://, about:, data:, or a domain name.`);
|
|
396
396
|
}
|
|
397
397
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
398
|
+
let response;
|
|
399
|
+
try {
|
|
400
|
+
response = await ctx.page.goto(url, {
|
|
401
|
+
waitUntil: p.waitUntil || "domcontentloaded",
|
|
402
|
+
...p.timeout ? { timeout: p.timeout } : {}
|
|
403
|
+
});
|
|
404
|
+
} catch (err) {
|
|
405
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
406
|
+
return fail(`Navigation failed: ${msg}`);
|
|
407
|
+
}
|
|
402
408
|
const ssr = await detectSsr(ctx.page);
|
|
403
409
|
return ok({ url, status: response?.status(), ...ssr ? { ssr } : {} });
|
|
404
410
|
}
|
|
@@ -713,6 +719,22 @@ var checkCommand = registerCommand({
|
|
|
713
719
|
return ok2({ selector: p.selector });
|
|
714
720
|
}
|
|
715
721
|
});
|
|
722
|
+
var uncheckCommand = registerCommand({
|
|
723
|
+
name: "uncheck",
|
|
724
|
+
description: "Uncheck checkbox or radio",
|
|
725
|
+
scope: "element",
|
|
726
|
+
selectorParams: ["selector"],
|
|
727
|
+
parameters: z2.object({
|
|
728
|
+
selector: z2.string()
|
|
729
|
+
}),
|
|
730
|
+
result: z2.object({
|
|
731
|
+
selector: z2.string()
|
|
732
|
+
}),
|
|
733
|
+
handler: async (p, ctx) => {
|
|
734
|
+
await ctx.page.uncheck(p.selector, { timeout: 1e4 });
|
|
735
|
+
return ok2({ selector: p.selector });
|
|
736
|
+
}
|
|
737
|
+
});
|
|
716
738
|
var hoverCommand = registerCommand({
|
|
717
739
|
name: "hover",
|
|
718
740
|
description: "Hover over element",
|
|
@@ -1254,7 +1276,7 @@ var setViewportCommand = registerCommand({
|
|
|
1254
1276
|
|
|
1255
1277
|
// src/commands/frame.ts
|
|
1256
1278
|
import { z as z12 } from "zod";
|
|
1257
|
-
import { ok as ok12, fail } from "@dyyz1993/xcli-core";
|
|
1279
|
+
import { ok as ok12, fail as fail2 } from "@dyyz1993/xcli-core";
|
|
1258
1280
|
var framesCommand = registerCommand({
|
|
1259
1281
|
name: "frames",
|
|
1260
1282
|
description: "List all frames in the current page",
|
|
@@ -1267,7 +1289,9 @@ var framesCommand = registerCommand({
|
|
|
1267
1289
|
}))
|
|
1268
1290
|
}),
|
|
1269
1291
|
handler: async (_p, ctx) => {
|
|
1270
|
-
const
|
|
1292
|
+
const discover = ctx.page.discoverFrames;
|
|
1293
|
+
const rawFrames = discover ? await discover.call(ctx.page) : ctx.page.frames();
|
|
1294
|
+
const frameList = rawFrames.map((frame, index) => ({
|
|
1271
1295
|
index,
|
|
1272
1296
|
name: frame.name(),
|
|
1273
1297
|
url: frame.url()
|
|
@@ -1289,17 +1313,18 @@ var frameCommand = registerCommand({
|
|
|
1289
1313
|
error: z12.string().optional()
|
|
1290
1314
|
}),
|
|
1291
1315
|
handler: async (p, ctx) => {
|
|
1292
|
-
const
|
|
1316
|
+
const discover = ctx.page.discoverFrames;
|
|
1317
|
+
const rawFrames = discover ? await discover.call(ctx.page) : ctx.page.frames();
|
|
1293
1318
|
let targetFrame;
|
|
1294
1319
|
if (p.index !== void 0) {
|
|
1295
|
-
targetFrame =
|
|
1320
|
+
targetFrame = rawFrames[p.index];
|
|
1296
1321
|
} else if (p.name !== void 0) {
|
|
1297
|
-
targetFrame =
|
|
1322
|
+
targetFrame = rawFrames.find((f) => f.name() === p.name);
|
|
1298
1323
|
} else {
|
|
1299
|
-
return
|
|
1324
|
+
return fail2("Must provide index or name");
|
|
1300
1325
|
}
|
|
1301
1326
|
if (!targetFrame) {
|
|
1302
|
-
return
|
|
1327
|
+
return fail2("Frame not found");
|
|
1303
1328
|
}
|
|
1304
1329
|
return ok12({
|
|
1305
1330
|
name: targetFrame.name(),
|
|
@@ -1945,7 +1970,7 @@ var actionsCommand = registerCommand({
|
|
|
1945
1970
|
|
|
1946
1971
|
// src/commands/scrape.ts
|
|
1947
1972
|
import { z as z15 } from "zod";
|
|
1948
|
-
import { ok as ok15, fail as
|
|
1973
|
+
import { ok as ok15, fail as fail3 } from "@dyyz1993/xcli-core";
|
|
1949
1974
|
|
|
1950
1975
|
// src/lib/html-to-markdown.ts
|
|
1951
1976
|
import * as cheerio from "cheerio";
|
|
@@ -2461,7 +2486,7 @@ var scrapeCommand = registerCommand({
|
|
|
2461
2486
|
}
|
|
2462
2487
|
}
|
|
2463
2488
|
}
|
|
2464
|
-
return
|
|
2489
|
+
return fail3(`Scrape failed after ${maxAttempts} attempt(s): ${lastError?.message ?? "unknown error"}`);
|
|
2465
2490
|
} finally {
|
|
2466
2491
|
await closeEphemeralContext(context);
|
|
2467
2492
|
}
|
|
@@ -3525,7 +3550,7 @@ ${errors.map((e) => ` - ${e.engine}: ${e.error}`).join("\n")}`
|
|
|
3525
3550
|
|
|
3526
3551
|
// src/commands/network.ts
|
|
3527
3552
|
import { z as z19 } from "zod";
|
|
3528
|
-
import { ok as ok19, fail as
|
|
3553
|
+
import { ok as ok19, fail as fail4 } from "@dyyz1993/xcli-core";
|
|
3529
3554
|
function extractPath2(url) {
|
|
3530
3555
|
try {
|
|
3531
3556
|
const u = new URL(url);
|
|
@@ -3690,7 +3715,7 @@ var networkCommand = registerCommand({
|
|
|
3690
3715
|
};
|
|
3691
3716
|
if (p.listen) {
|
|
3692
3717
|
const page2 = ctx.page;
|
|
3693
|
-
if (!page2) return
|
|
3718
|
+
if (!page2) return fail4("No active page. Use --cdp to connect first.");
|
|
3694
3719
|
const captures = [];
|
|
3695
3720
|
const consoleMessages = [];
|
|
3696
3721
|
const wsCaptures = [];
|
|
@@ -4347,7 +4372,7 @@ function parseMarkdownResults(rawText) {
|
|
|
4347
4372
|
|
|
4348
4373
|
// src/commands/snapshot.ts
|
|
4349
4374
|
import { z as z21 } from "zod";
|
|
4350
|
-
import { ok as ok20, fail as
|
|
4375
|
+
import { ok as ok20, fail as fail5, normalizeTips as normalizeTips3 } from "@dyyz1993/xcli-core";
|
|
4351
4376
|
|
|
4352
4377
|
// src/runtime/ref-store.ts
|
|
4353
4378
|
var sessions = /* @__PURE__ */ new Map();
|
|
@@ -5303,7 +5328,7 @@ var snapshotCommand = registerCommand({
|
|
|
5303
5328
|
persistSemantics(url, aria);
|
|
5304
5329
|
return ok20({ url, title, aria, text, dom }, normalizeTips3(tips));
|
|
5305
5330
|
}
|
|
5306
|
-
return
|
|
5331
|
+
return fail5(`Unknown snapshot type: ${p.type}`);
|
|
5307
5332
|
}
|
|
5308
5333
|
});
|
|
5309
5334
|
function persistSemantics(url, aria) {
|
|
@@ -5472,7 +5497,7 @@ var waitForCommand = registerCommand({
|
|
|
5472
5497
|
|
|
5473
5498
|
// src/commands/tab.ts
|
|
5474
5499
|
import { z as z23 } from "zod";
|
|
5475
|
-
import { ok as ok22, fail as
|
|
5500
|
+
import { ok as ok22, fail as fail6 } from "@dyyz1993/xcli-core";
|
|
5476
5501
|
var TabParams = z23.object({
|
|
5477
5502
|
subcommand: z23.enum(["list", "new", "close", "switch"]),
|
|
5478
5503
|
url: z23.string().optional(),
|
|
@@ -5499,7 +5524,7 @@ var tabCommand = registerCommand({
|
|
|
5499
5524
|
case "switch":
|
|
5500
5525
|
return handleSwitch(p, pages, ctx);
|
|
5501
5526
|
default:
|
|
5502
|
-
return
|
|
5527
|
+
return fail6(`Unknown subcommand: ${p.subcommand}`);
|
|
5503
5528
|
}
|
|
5504
5529
|
}
|
|
5505
5530
|
});
|
|
@@ -5556,11 +5581,11 @@ async function handleNew(p, _pages, ctx) {
|
|
|
5556
5581
|
}
|
|
5557
5582
|
async function handleClose(p, pages, ctx) {
|
|
5558
5583
|
if (pages.length <= 1) {
|
|
5559
|
-
return
|
|
5584
|
+
return fail6("Cannot close the last remaining tab");
|
|
5560
5585
|
}
|
|
5561
5586
|
const closeIndex = p.index ?? pages.indexOf(ctx.page);
|
|
5562
5587
|
if (closeIndex < 0 || closeIndex >= pages.length) {
|
|
5563
|
-
return
|
|
5588
|
+
return fail6(`Invalid tab index: ${closeIndex}. Valid range: 0-${pages.length - 1}`);
|
|
5564
5589
|
}
|
|
5565
5590
|
const pageToClose = pages[closeIndex];
|
|
5566
5591
|
const isActivePage = pageToClose === ctx.page;
|
|
@@ -5583,10 +5608,10 @@ async function handleClose(p, pages, ctx) {
|
|
|
5583
5608
|
}
|
|
5584
5609
|
async function handleSwitch(p, pages, ctx) {
|
|
5585
5610
|
if (p.index === void 0) {
|
|
5586
|
-
return
|
|
5611
|
+
return fail6("Parameter --index is required for switch subcommand");
|
|
5587
5612
|
}
|
|
5588
5613
|
if (p.index < 0 || p.index >= pages.length) {
|
|
5589
|
-
return
|
|
5614
|
+
return fail6(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
|
|
5590
5615
|
}
|
|
5591
5616
|
const targetPage = pages[p.index];
|
|
5592
5617
|
await targetPage.bringToFront().catch(() => {
|
|
@@ -5832,7 +5857,7 @@ registerCommandDefinition("addinitscript", ["script"]);
|
|
|
5832
5857
|
|
|
5833
5858
|
// src/commands/find.ts
|
|
5834
5859
|
import { z as z25 } from "zod";
|
|
5835
|
-
import { ok as ok24, fail as
|
|
5860
|
+
import { ok as ok24, fail as fail7, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
|
|
5836
5861
|
var actionSchema2 = z25.enum(["click", "fill", "type", "select", "hover", "check"]);
|
|
5837
5862
|
var findCommand = registerCommand({
|
|
5838
5863
|
name: "find",
|
|
@@ -5873,7 +5898,7 @@ var findCommand = registerCommand({
|
|
|
5873
5898
|
});
|
|
5874
5899
|
const count = await locator.count();
|
|
5875
5900
|
if (count === 0) {
|
|
5876
|
-
return
|
|
5901
|
+
return fail7(`No element found with ${p.strategy}="${p.value}"`);
|
|
5877
5902
|
}
|
|
5878
5903
|
const tips = [];
|
|
5879
5904
|
const target = selectTarget(locator, p.strategy);
|
|
@@ -5885,15 +5910,15 @@ var findCommand = registerCommand({
|
|
|
5885
5910
|
await target.click({ timeout: p.timeout, force: true });
|
|
5886
5911
|
return okWithTips({ matched: count, selector, action: "click" }, tips);
|
|
5887
5912
|
} else if (actionName === "fill") {
|
|
5888
|
-
if (actionValue === void 0) return
|
|
5913
|
+
if (actionValue === void 0) return fail7("find fill requires a value");
|
|
5889
5914
|
await target.fill(actionValue, { timeout: p.timeout, force: true });
|
|
5890
5915
|
return okWithTips({ matched: count, selector, action: `fill("${actionValue}")` }, tips);
|
|
5891
5916
|
} else if (actionName === "type") {
|
|
5892
|
-
if (actionValue === void 0) return
|
|
5917
|
+
if (actionValue === void 0) return fail7("find type requires a value");
|
|
5893
5918
|
await target.type(actionValue, { delay: 10, timeout: p.timeout });
|
|
5894
5919
|
return okWithTips({ matched: count, selector, action: `type("${actionValue}")` }, tips);
|
|
5895
5920
|
} else if (actionName === "select") {
|
|
5896
|
-
if (actionValue === void 0) return
|
|
5921
|
+
if (actionValue === void 0) return fail7("find select requires a value");
|
|
5897
5922
|
await target.selectOption(actionValue);
|
|
5898
5923
|
return okWithTips({ matched: count, selector, action: `select("${actionValue}")` }, tips);
|
|
5899
5924
|
} else if (actionName === "hover") {
|
|
@@ -7317,7 +7342,7 @@ async function guardCheck(commandName) {
|
|
|
7317
7342
|
}
|
|
7318
7343
|
}
|
|
7319
7344
|
function errorResult(message) {
|
|
7320
|
-
return { ...
|
|
7345
|
+
return { ...fail8(message), duration: 0 };
|
|
7321
7346
|
}
|
|
7322
7347
|
function tipsToMessages(tips) {
|
|
7323
7348
|
if (!tips || tips.length === 0) return [];
|
|
@@ -7353,7 +7378,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7353
7378
|
}
|
|
7354
7379
|
let targetPageOverride = null;
|
|
7355
7380
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7356
|
-
const { findTargetPage } = await import("./browser-
|
|
7381
|
+
const { findTargetPage } = await import("./browser-WMQRPYXX.js");
|
|
7357
7382
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7358
7383
|
if (!targetPageOverride) {
|
|
7359
7384
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -7557,7 +7582,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7557
7582
|
duration,
|
|
7558
7583
|
timestamp: start
|
|
7559
7584
|
});
|
|
7560
|
-
return { ...
|
|
7585
|
+
return { ...fail8(errorMessage), duration };
|
|
7561
7586
|
} finally {
|
|
7562
7587
|
}
|
|
7563
7588
|
}
|
|
@@ -7598,7 +7623,7 @@ async function executeChain(input, options) {
|
|
|
7598
7623
|
results.push({
|
|
7599
7624
|
command: cmdName,
|
|
7600
7625
|
raw: cmdStr,
|
|
7601
|
-
...
|
|
7626
|
+
...fail8(`Plugin "${cmdName}" requires a sub-command`),
|
|
7602
7627
|
duration: 0
|
|
7603
7628
|
});
|
|
7604
7629
|
if (type === "and") {
|
|
@@ -7617,7 +7642,7 @@ async function executeChain(input, options) {
|
|
|
7617
7642
|
results.push({
|
|
7618
7643
|
command: cmdName,
|
|
7619
7644
|
raw: cmdStr,
|
|
7620
|
-
...
|
|
7645
|
+
...fail8(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
|
|
7621
7646
|
duration: 0
|
|
7622
7647
|
});
|
|
7623
7648
|
if (type === "and") {
|
|
@@ -7749,7 +7774,7 @@ async function executeChain(input, options) {
|
|
|
7749
7774
|
results.push({
|
|
7750
7775
|
command: `${cmdName} ${subCommand}`,
|
|
7751
7776
|
raw: cmdStr,
|
|
7752
|
-
...
|
|
7777
|
+
...fail8(errorMessage),
|
|
7753
7778
|
duration: duration2
|
|
7754
7779
|
});
|
|
7755
7780
|
if (type === "and") {
|
|
@@ -7821,7 +7846,7 @@ async function executeChain(input, options) {
|
|
|
7821
7846
|
}
|
|
7822
7847
|
}
|
|
7823
7848
|
function isChainInput(input) {
|
|
7824
|
-
return /\s&&\s|\s;\s|\s,\s|\s\+\s|\s->\s/.test(input);
|
|
7849
|
+
return /\s&&\s|\|\|\s|\s;\s|\s,\s|\s\+\s|\s->\s/.test(input);
|
|
7825
7850
|
}
|
|
7826
7851
|
|
|
7827
7852
|
// src/context.ts
|
|
@@ -10313,6 +10338,17 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
10313
10338
|
};
|
|
10314
10339
|
break;
|
|
10315
10340
|
}
|
|
10341
|
+
case "tab": {
|
|
10342
|
+
const tabSub = args[0];
|
|
10343
|
+
const validSubs = ["list", "new", "close", "switch"];
|
|
10344
|
+
cmdName = "tab";
|
|
10345
|
+
params = {
|
|
10346
|
+
subcommand: validSubs.includes(tabSub) ? tabSub : options.subcommand,
|
|
10347
|
+
url: args[1] || options.url,
|
|
10348
|
+
index: options.index ? Number(options.index) : void 0
|
|
10349
|
+
};
|
|
10350
|
+
break;
|
|
10351
|
+
}
|
|
10316
10352
|
default:
|
|
10317
10353
|
cmdName = command;
|
|
10318
10354
|
params = { ...options };
|
|
@@ -11135,6 +11171,7 @@ async function handleConvert(args, _mode) {
|
|
|
11135
11171
|
const { generateJSScript: generateJSScript2, generatePythonScript: generatePythonScript2, generateBashScript: generateBashScript2 } = await import("./convert-R3XXYKC6.js");
|
|
11136
11172
|
const content = fs6.readFileSync(filePath, "utf-8");
|
|
11137
11173
|
const recording = yaml3.parse(content);
|
|
11174
|
+
if (recording.actions && !recording.events) recording.events = recording.actions;
|
|
11138
11175
|
const ext = path5.extname(outputPath).toLowerCase();
|
|
11139
11176
|
let script;
|
|
11140
11177
|
if (ext === ".py") {
|
|
@@ -11146,7 +11183,7 @@ async function handleConvert(args, _mode) {
|
|
|
11146
11183
|
}
|
|
11147
11184
|
fs6.writeFileSync(outputPath, script);
|
|
11148
11185
|
fs6.chmodSync(outputPath, 493);
|
|
11149
|
-
const eventCount = (recording.events || []).length;
|
|
11186
|
+
const eventCount = (recording.events || recording.actions || []).length;
|
|
11150
11187
|
console.log(`Converted ${filePath} -> ${outputPath}`);
|
|
11151
11188
|
console.log(` Events: ${eventCount}, Start URL: ${recording.startUrl}`);
|
|
11152
11189
|
console.log(` Run: ${ext === ".py" ? "python" : ext === ".sh" ? "./" : "node"} ${outputPath}`);
|
|
@@ -11157,7 +11194,7 @@ async function handleExtract(args, _mode) {
|
|
|
11157
11194
|
console.error("Usage: xbrowser extract <recording.yaml>");
|
|
11158
11195
|
process.exit(1);
|
|
11159
11196
|
}
|
|
11160
|
-
const { extractAndSave: extractAndSave2, printExtractSummary: printExtractSummary2 } = await import("./extract-
|
|
11197
|
+
const { extractAndSave: extractAndSave2, printExtractSummary: printExtractSummary2 } = await import("./extract-RM62AJXW.js");
|
|
11161
11198
|
const { summary, outputPath } = extractAndSave2(filePath);
|
|
11162
11199
|
printExtractSummary2(summary);
|
|
11163
11200
|
console.log(`
|
|
@@ -11170,7 +11207,7 @@ async function handleFilter(args, _mode, options) {
|
|
|
11170
11207
|
console.error("Usage: xbrowser filter <input.yaml> <output.yaml> [--exclude type1,type2]");
|
|
11171
11208
|
process.exit(1);
|
|
11172
11209
|
}
|
|
11173
|
-
const { filterRecording: filterRecording2, parseExcludeTypes: parseExcludeTypes2 } = await import("./filter-
|
|
11210
|
+
const { filterRecording: filterRecording2, parseExcludeTypes: parseExcludeTypes2 } = await import("./filter-K6FGRJQU.js");
|
|
11174
11211
|
const excludeArgs = args.slice(2).concat(
|
|
11175
11212
|
Object.entries(options || {}).flatMap(
|
|
11176
11213
|
([k, v]) => k.startsWith("exclude") ? [`--${k}${typeof v === "string" ? "=" + v : ""}`] : []
|
|
@@ -12625,7 +12662,7 @@ function extractCdpFromArgv(argv) {
|
|
|
12625
12662
|
return process.env.XBROWSER_CDP;
|
|
12626
12663
|
}
|
|
12627
12664
|
async function handleStdinMode(stdinCommands, argv) {
|
|
12628
|
-
const chain = stdinCommands.join("
|
|
12665
|
+
const chain = stdinCommands.join(" ; ");
|
|
12629
12666
|
const cdpEndpoint = argv ? extractCdpFromArgv(argv) : void 0;
|
|
12630
12667
|
const sessionName = argv ? extractSessionNameFromArgv(argv) : "default";
|
|
12631
12668
|
const chainResult = await executeChain(chain, { fileMode: true, cdpEndpoint, sessionName });
|
|
@@ -12888,6 +12925,13 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12888
12925
|
for (const step of chainResult.steps) {
|
|
12889
12926
|
if (step.success) {
|
|
12890
12927
|
console.log(`[OK] ${step.raw}`);
|
|
12928
|
+
if (step.data && typeof step.data === "object") {
|
|
12929
|
+
const d = step.data;
|
|
12930
|
+
for (const [k, v] of Object.entries(d)) {
|
|
12931
|
+
if (k !== "ok" && k !== "success")
|
|
12932
|
+
console.log(` ${k}: ${typeof v === "string" ? v : JSON.stringify(v)}`);
|
|
12933
|
+
}
|
|
12934
|
+
}
|
|
12891
12935
|
if (step.tips?.length) {
|
|
12892
12936
|
for (const tip of step.tips) {
|
|
12893
12937
|
console.log(` \u{1F4A1} ${tip}`);
|
|
@@ -12897,6 +12941,9 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12897
12941
|
console.error(`[FAIL] ${step.raw}: ${step.message}`);
|
|
12898
12942
|
}
|
|
12899
12943
|
}
|
|
12944
|
+
if (chainResult.stoppedReason) {
|
|
12945
|
+
console.error(`Stopped: ${chainResult.stoppedReason}`);
|
|
12946
|
+
}
|
|
12900
12947
|
if (!chainResult.success) throw new Error("Command failed");
|
|
12901
12948
|
return;
|
|
12902
12949
|
}
|
|
@@ -16076,7 +16123,7 @@ var DataCollector = class {
|
|
|
16076
16123
|
return results;
|
|
16077
16124
|
}
|
|
16078
16125
|
async createBrowserContext() {
|
|
16079
|
-
const { launch } = await import("./cdp-driver-
|
|
16126
|
+
const { launch } = await import("./cdp-driver-72HOBP4C.js");
|
|
16080
16127
|
const { browser } = await launch({
|
|
16081
16128
|
headless: true,
|
|
16082
16129
|
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-72HOBP4C.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.
|
|
3
|
+
"version": "1.4.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": {
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"prepare": "husky"
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@dyyz1993/xcli-core": "^0.
|
|
87
|
+
"@dyyz1993/xcli-core": "^0.16.0",
|
|
88
88
|
"@types/react-syntax-highlighter": "^15.5.13",
|
|
89
89
|
"@types/turndown": "^5.0.6",
|
|
90
90
|
"cheerio": "^1.2.0",
|