@xbrowser/cli 1.8.4 → 1.8.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/dist/{browser-4PIVOYCW.js → browser-LW2MDJE4.js} +1 -1
- package/dist/{browser-RJIRI2H5.js → browser-TLIDFFEG.js} +1 -1
- package/dist/{browser-KVTJQKBA.js → browser-XPKM344Y.js} +1 -1
- package/dist/{chunk-IGWWPMEQ.js → chunk-CJJ564VK.js} +1 -1
- package/dist/{chunk-2SVQTI2O.js → chunk-FL6DOSWV.js} +48 -20
- package/dist/{chunk-6QGZN5U7.js → chunk-HXLMMSU3.js} +1 -1
- package/dist/{chunk-ACFE6PKF.js → chunk-RMYEHTLS.js} +48 -20
- package/dist/{chunk-35DOHDTA.js → chunk-SJLRCE6N.js} +1 -1
- package/dist/cli.js +177 -75
- package/dist/daemon-main.js +29 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +176 -74
- package/dist/{session-recorder-RTDGURIJ.js → session-recorder-33UKWCIR.js} +1 -1
- package/dist/{session-recorder-YI7YYM36.js → session-recorder-BMIJ3ZJM.js} +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
} from "./chunk-GJAV3QGG.js";
|
|
58
58
|
import {
|
|
59
59
|
SessionRecorder
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-RMYEHTLS.js";
|
|
61
61
|
import {
|
|
62
62
|
addKnownIssue,
|
|
63
63
|
getKnowledgePath,
|
|
@@ -82,7 +82,7 @@ import {
|
|
|
82
82
|
resolveLaunchOpts,
|
|
83
83
|
saveSessionDiskMeta,
|
|
84
84
|
setActivePage
|
|
85
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-CJJ564VK.js";
|
|
86
86
|
import "./chunk-VJNMAWPZ.js";
|
|
87
87
|
import "./chunk-TNEN6VQ2.js";
|
|
88
88
|
import {
|
|
@@ -7525,9 +7525,14 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7525
7525
|
const { _target: _u, ...rest } = params;
|
|
7526
7526
|
params = rest;
|
|
7527
7527
|
}
|
|
7528
|
+
const _tabIndex = params._tabIndex;
|
|
7529
|
+
if (_tabIndex !== void 0) {
|
|
7530
|
+
const { _tabIndex: _u, ...rest } = params;
|
|
7531
|
+
params = rest;
|
|
7532
|
+
}
|
|
7528
7533
|
let targetPageOverride = null;
|
|
7529
7534
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7530
|
-
const { findTargetPage } = await import("./browser-
|
|
7535
|
+
const { findTargetPage } = await import("./browser-TLIDFFEG.js");
|
|
7531
7536
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7532
7537
|
if (!targetPageOverride) {
|
|
7533
7538
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -7599,6 +7604,16 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7599
7604
|
cliName: "xbrowser",
|
|
7600
7605
|
tips: new TipCollector2()
|
|
7601
7606
|
};
|
|
7607
|
+
if (_tabIndex !== void 0 && session?.context) {
|
|
7608
|
+
const pages = session.context.pages();
|
|
7609
|
+
if (_tabIndex >= 0 && _tabIndex < pages.length) {
|
|
7610
|
+
const targetPage = pages[_tabIndex];
|
|
7611
|
+
await targetPage.bringToFront().catch(() => {
|
|
7612
|
+
});
|
|
7613
|
+
setActivePage(session, targetPage);
|
|
7614
|
+
ctx.page = targetPage;
|
|
7615
|
+
}
|
|
7616
|
+
}
|
|
7602
7617
|
const start = Date.now();
|
|
7603
7618
|
if (session) {
|
|
7604
7619
|
streamCommandEvent(session.id, {
|
|
@@ -7627,7 +7642,17 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7627
7642
|
if (hooks.length > 0 && session?.page) {
|
|
7628
7643
|
await Promise.all(hooks.map((h) => h.onBeforeCommand?.({ page: session.page, command: commandName, params })));
|
|
7629
7644
|
}
|
|
7630
|
-
|
|
7645
|
+
let raw;
|
|
7646
|
+
const handlerPromise = command.handler(params, ctx);
|
|
7647
|
+
if (extraOpts?.timeout && extraOpts.timeout > 0) {
|
|
7648
|
+
const timeoutMs = extraOpts.timeout;
|
|
7649
|
+
const timeoutPromise = new Promise(
|
|
7650
|
+
(_, reject) => setTimeout(() => reject(new Error(`Command timed out after ${timeoutMs}ms`)), timeoutMs)
|
|
7651
|
+
);
|
|
7652
|
+
raw = await Promise.race([handlerPromise, timeoutPromise]);
|
|
7653
|
+
} else {
|
|
7654
|
+
raw = await handlerPromise;
|
|
7655
|
+
}
|
|
7631
7656
|
const end = Date.now();
|
|
7632
7657
|
const duration = end - start;
|
|
7633
7658
|
let hookOutputs;
|
|
@@ -8201,16 +8226,29 @@ var configBuiltin = {
|
|
|
8201
8226
|
execute: async (args, _options, _ctx) => {
|
|
8202
8227
|
const [subcommand, ...rest] = args;
|
|
8203
8228
|
if (!subcommand || subcommand === "list") {
|
|
8229
|
+
let flatten2 = function(obj, prefix = "") {
|
|
8230
|
+
const entries2 = [];
|
|
8231
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
8232
|
+
const fullKey = prefix ? `${prefix}.${k}` : k;
|
|
8233
|
+
if (v && typeof v === "object" && !Array.isArray(v)) {
|
|
8234
|
+
entries2.push(...flatten2(v, fullKey));
|
|
8235
|
+
} else {
|
|
8236
|
+
entries2.push({ key: fullKey, value: v });
|
|
8237
|
+
}
|
|
8238
|
+
}
|
|
8239
|
+
return entries2;
|
|
8240
|
+
};
|
|
8241
|
+
var flatten = flatten2;
|
|
8204
8242
|
const config = loadConfig();
|
|
8205
|
-
const
|
|
8206
|
-
if (
|
|
8243
|
+
const entries = flatten2(config);
|
|
8244
|
+
if (entries.length === 0) {
|
|
8207
8245
|
console.log("Configuration is empty");
|
|
8208
8246
|
return;
|
|
8209
8247
|
}
|
|
8210
8248
|
console.log("Configuration:");
|
|
8211
8249
|
console.log("");
|
|
8212
|
-
for (const
|
|
8213
|
-
console.log(` ${
|
|
8250
|
+
for (const { key, value } of entries) {
|
|
8251
|
+
console.log(` ${key} = ${value}`);
|
|
8214
8252
|
}
|
|
8215
8253
|
return;
|
|
8216
8254
|
}
|
|
@@ -9009,6 +9047,39 @@ function outputError(message) {
|
|
|
9009
9047
|
console.error(formatted);
|
|
9010
9048
|
process.exit(1);
|
|
9011
9049
|
}
|
|
9050
|
+
function outputEnvelope(result, meta, mode) {
|
|
9051
|
+
if (mode !== "json" && mode !== "yaml") {
|
|
9052
|
+
if (!result.success) {
|
|
9053
|
+
outputError(result.message || "Unknown error");
|
|
9054
|
+
return;
|
|
9055
|
+
}
|
|
9056
|
+
outputResult(result.data, mode);
|
|
9057
|
+
return;
|
|
9058
|
+
}
|
|
9059
|
+
const { command, ...extraMeta } = meta;
|
|
9060
|
+
const commandResult = {
|
|
9061
|
+
success: result.success,
|
|
9062
|
+
data: result.data,
|
|
9063
|
+
message: result.message,
|
|
9064
|
+
tips: [],
|
|
9065
|
+
meta: {
|
|
9066
|
+
duration: result.duration ?? 0,
|
|
9067
|
+
...extraMeta
|
|
9068
|
+
}
|
|
9069
|
+
};
|
|
9070
|
+
const formatted = outputFormatter.formatEnvelope(commandResult, {
|
|
9071
|
+
command,
|
|
9072
|
+
extraMeta,
|
|
9073
|
+
mode
|
|
9074
|
+
});
|
|
9075
|
+
console.log(formatted);
|
|
9076
|
+
if (result.tips?.length) {
|
|
9077
|
+
for (const tip of result.tips) {
|
|
9078
|
+
const text = typeof tip === "string" ? tip : tip.message;
|
|
9079
|
+
if (text) console.error(` \u{1F4A1} ${text}`);
|
|
9080
|
+
}
|
|
9081
|
+
}
|
|
9082
|
+
}
|
|
9012
9083
|
|
|
9013
9084
|
// src/builtins/plugin.ts
|
|
9014
9085
|
var pluginLoader2 = null;
|
|
@@ -10573,9 +10644,13 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
10573
10644
|
if (target) {
|
|
10574
10645
|
params = { ...params, _target: target };
|
|
10575
10646
|
}
|
|
10647
|
+
const tabIndex = options.tab;
|
|
10648
|
+
if (tabIndex !== void 0) {
|
|
10649
|
+
params = { ...params, _tabIndex: Number(tabIndex) };
|
|
10650
|
+
}
|
|
10576
10651
|
const result = cdpEndpoint ? await executeCommand(cmdName, params, sessionName, { cdpEndpoint }) : await executeCommand(cmdName, params, sessionName);
|
|
10577
10652
|
if (mode === "json" || mode === "yaml") {
|
|
10578
|
-
|
|
10653
|
+
outputEnvelope(result, { command: cmdName }, mode);
|
|
10579
10654
|
} else if (!result.success) {
|
|
10580
10655
|
outputError(result.message || "Command failed");
|
|
10581
10656
|
} else {
|
|
@@ -10635,7 +10710,7 @@ async function handleSession(args, options, mode, _cdpEndpoint) {
|
|
|
10635
10710
|
}
|
|
10636
10711
|
} catch {
|
|
10637
10712
|
}
|
|
10638
|
-
|
|
10713
|
+
outputEnvelope({ success: true, data: { closed: count, all: true } }, { command: "session close" }, mode);
|
|
10639
10714
|
} else {
|
|
10640
10715
|
const name = options.session || options.name || process.env.XBROWSER_SESSION || "default";
|
|
10641
10716
|
try {
|
|
@@ -10643,7 +10718,7 @@ async function handleSession(args, options, mode, _cdpEndpoint) {
|
|
|
10643
10718
|
} catch {
|
|
10644
10719
|
}
|
|
10645
10720
|
await closeSession(name);
|
|
10646
|
-
|
|
10721
|
+
outputEnvelope({ success: true, data: { name } }, { command: "session close" }, mode);
|
|
10647
10722
|
}
|
|
10648
10723
|
break;
|
|
10649
10724
|
}
|
|
@@ -10651,10 +10726,10 @@ async function handleSession(args, options, mode, _cdpEndpoint) {
|
|
|
10651
10726
|
case "ls": {
|
|
10652
10727
|
try {
|
|
10653
10728
|
const sessions2 = await forwardSessionList();
|
|
10654
|
-
|
|
10729
|
+
outputEnvelope({ success: true, data: { sessions: sessions2 } }, { command: "session list" }, mode);
|
|
10655
10730
|
} catch {
|
|
10656
10731
|
const sessions2 = await listSessions();
|
|
10657
|
-
|
|
10732
|
+
outputEnvelope({ success: true, data: { sessions: sessions2 } }, { command: "session list" }, mode);
|
|
10658
10733
|
}
|
|
10659
10734
|
break;
|
|
10660
10735
|
}
|
|
@@ -10669,7 +10744,7 @@ async function handleSession(args, options, mode, _cdpEndpoint) {
|
|
|
10669
10744
|
await stopDaemonProcess();
|
|
10670
10745
|
} catch {
|
|
10671
10746
|
}
|
|
10672
|
-
|
|
10747
|
+
outputEnvelope({ success: true, data: { name, killed: true, daemon: "stopped" } }, { command: "session kill" }, mode);
|
|
10673
10748
|
break;
|
|
10674
10749
|
}
|
|
10675
10750
|
case "kill-all": {
|
|
@@ -10688,7 +10763,7 @@ async function handleSession(args, options, mode, _cdpEndpoint) {
|
|
|
10688
10763
|
} catch {
|
|
10689
10764
|
}
|
|
10690
10765
|
const cleaned = cleanSessionFiles();
|
|
10691
|
-
|
|
10766
|
+
outputEnvelope({ success: true, data: { sessionsCleaned: cleaned, daemon: "killed" } }, { command: "session kill-all" }, mode);
|
|
10692
10767
|
break;
|
|
10693
10768
|
}
|
|
10694
10769
|
default:
|
|
@@ -10808,7 +10883,7 @@ async function handleSearch(args, options, mode) {
|
|
|
10808
10883
|
}
|
|
10809
10884
|
}
|
|
10810
10885
|
if (mode === "json") {
|
|
10811
|
-
|
|
10886
|
+
outputEnvelope({ success: true, data: { results, total: results.length } }, { command: "plugin search" }, mode);
|
|
10812
10887
|
} else {
|
|
10813
10888
|
if (results.length === 0) {
|
|
10814
10889
|
console.log("No plugins found");
|
|
@@ -10837,7 +10912,7 @@ async function handlePluginInfo(args, options, mode) {
|
|
|
10837
10912
|
if (pluginInfo) {
|
|
10838
10913
|
const d = pluginInfo;
|
|
10839
10914
|
if (mode === "json") {
|
|
10840
|
-
|
|
10915
|
+
outputEnvelope({ success: true, data: { source: "marketplace", ...d } }, { command: "plugin info" }, mode);
|
|
10841
10916
|
return;
|
|
10842
10917
|
}
|
|
10843
10918
|
console.log(`\u540D\u79F0: ${d.name || ""}`);
|
|
@@ -10863,7 +10938,7 @@ async function handlePluginInfo(args, options, mode) {
|
|
|
10863
10938
|
const pkg = latest && versions?.[latest];
|
|
10864
10939
|
if (pkg) {
|
|
10865
10940
|
if (mode === "json") {
|
|
10866
|
-
|
|
10941
|
+
outputEnvelope({ success: true, data: { source: "npm", name: pkg.name, version: latest, description: pkg.description } }, { command: "plugin info" }, mode);
|
|
10867
10942
|
return;
|
|
10868
10943
|
}
|
|
10869
10944
|
console.log(`\u540D\u79F0: ${pkg.name || ""}`);
|
|
@@ -10892,7 +10967,7 @@ async function handlePluginSchema(args, mode) {
|
|
|
10892
10967
|
return;
|
|
10893
10968
|
}
|
|
10894
10969
|
if (mode === "json") {
|
|
10895
|
-
|
|
10970
|
+
outputEnvelope({ success: true, data: contract }, { command: "plugin schema" }, mode);
|
|
10896
10971
|
return;
|
|
10897
10972
|
}
|
|
10898
10973
|
if ("commands" in contract) {
|
|
@@ -10970,8 +11045,9 @@ async function handlePlugin(args, options, mode) {
|
|
|
10970
11045
|
}
|
|
10971
11046
|
} catch {
|
|
10972
11047
|
}
|
|
10973
|
-
|
|
10974
|
-
{
|
|
11048
|
+
outputEnvelope(
|
|
11049
|
+
{ success: true, data: { name: result.name, source: result.source, path: result.path } },
|
|
11050
|
+
{ command: "plugin install" },
|
|
10975
11051
|
mode
|
|
10976
11052
|
);
|
|
10977
11053
|
break;
|
|
@@ -10990,7 +11066,7 @@ async function handlePlugin(args, options, mode) {
|
|
|
10990
11066
|
await loader.reloadPlugin(name);
|
|
10991
11067
|
} catch {
|
|
10992
11068
|
}
|
|
10993
|
-
|
|
11069
|
+
outputEnvelope({ success: true, data: { name } }, { command: "plugin uninstall" }, mode);
|
|
10994
11070
|
break;
|
|
10995
11071
|
}
|
|
10996
11072
|
case "list": {
|
|
@@ -11012,7 +11088,7 @@ async function handlePlugin(args, options, mode) {
|
|
|
11012
11088
|
};
|
|
11013
11089
|
});
|
|
11014
11090
|
if (mode === "json") {
|
|
11015
|
-
|
|
11091
|
+
outputEnvelope({ success: true, data: { plugins: enrichedPlugins } }, { command: "plugin list" }, mode);
|
|
11016
11092
|
} else {
|
|
11017
11093
|
if (enrichedPlugins.length === 0) {
|
|
11018
11094
|
console.log("No plugins installed");
|
|
@@ -11048,7 +11124,7 @@ Total: ${enrichedPlugins.length} plugins`);
|
|
|
11048
11124
|
} catch {
|
|
11049
11125
|
outputError(`Plugin "${name}" not found. Use 'xbrowser plugin list' to see installed plugins.`);
|
|
11050
11126
|
}
|
|
11051
|
-
|
|
11127
|
+
outputEnvelope({ success: true, data: { name } }, { command: "plugin reload" }, mode);
|
|
11052
11128
|
break;
|
|
11053
11129
|
}
|
|
11054
11130
|
case "search":
|
|
@@ -11080,24 +11156,22 @@ function handleDaemon(args, options, mode) {
|
|
|
11080
11156
|
case "start": {
|
|
11081
11157
|
const port = options.port ? Number(options.port) : 9224;
|
|
11082
11158
|
startDaemonProcess(port).then(
|
|
11083
|
-
(config) =>
|
|
11159
|
+
(config) => outputEnvelope({ success: true, data: { pid: config.pid, port: config.port } }, { command: "daemon start" }, mode)
|
|
11084
11160
|
).catch(
|
|
11085
11161
|
(e) => outputError(e instanceof Error ? e.message : String(e))
|
|
11086
11162
|
);
|
|
11087
11163
|
break;
|
|
11088
11164
|
}
|
|
11089
11165
|
case "stop": {
|
|
11090
|
-
stopDaemonProcess().then(() =>
|
|
11166
|
+
stopDaemonProcess().then(() => outputEnvelope({ success: true, data: {} }, { command: "daemon stop" }, mode)).catch(
|
|
11091
11167
|
(e) => outputError(e instanceof Error ? e.message : String(e))
|
|
11092
11168
|
);
|
|
11093
11169
|
break;
|
|
11094
11170
|
}
|
|
11095
11171
|
case "status": {
|
|
11096
11172
|
const status = getDaemonProcessStatus();
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
mode
|
|
11100
|
-
);
|
|
11173
|
+
const statusData = status.running ? { running: true, pid: status.pid, port: status.port } : { running: false };
|
|
11174
|
+
outputEnvelope({ success: true, data: statusData }, { command: "daemon status" }, mode);
|
|
11101
11175
|
break;
|
|
11102
11176
|
}
|
|
11103
11177
|
default:
|
|
@@ -11475,7 +11549,7 @@ async function handleFilter(args, _mode, options) {
|
|
|
11475
11549
|
console.log(` Original: ${result.originalCount}, After: ${result.filteredCount}, Removed: ${result.removed} (${result.percentage}%)`);
|
|
11476
11550
|
}
|
|
11477
11551
|
async function handleGeneratePlugin(sessionName, pluginName, outputDir) {
|
|
11478
|
-
const { SessionRecorder: SessionRecorder2 } = await import("./session-recorder-
|
|
11552
|
+
const { SessionRecorder: SessionRecorder2 } = await import("./session-recorder-33UKWCIR.js");
|
|
11479
11553
|
const { readSiteKnowledge: readSiteKnowledge2, toMarkdown } = await import("./site-knowledge-SYC6VCDB.js");
|
|
11480
11554
|
const { mkdirSync: mkdirSync11, writeFileSync: writeFileSync13 } = await import("fs");
|
|
11481
11555
|
const { join: join14 } = await import("path");
|
|
@@ -12822,7 +12896,8 @@ var KNOWN_GLOBAL_OPTIONS = /* @__PURE__ */ new Set([
|
|
|
12822
12896
|
"port",
|
|
12823
12897
|
"token",
|
|
12824
12898
|
"timeout",
|
|
12825
|
-
"headless"
|
|
12899
|
+
"headless",
|
|
12900
|
+
"tab"
|
|
12826
12901
|
]);
|
|
12827
12902
|
function showCommandHelp(siteName, cmd, siteConfig, mode) {
|
|
12828
12903
|
const c = cmd;
|
|
@@ -12976,20 +13051,28 @@ async function handleEvalMode(argv) {
|
|
|
12976
13051
|
}
|
|
12977
13052
|
async function handleChainInput(input, argv) {
|
|
12978
13053
|
const cdpEndpoint = argv ? extractCdpFromArgv(argv) : void 0;
|
|
12979
|
-
const
|
|
13054
|
+
const hasJson = argv ? argv.some((a) => a === "--json" || a.startsWith("--json=") || a.includes(" --json") || a.startsWith("--json")) || argv.includes("-j") : false;
|
|
13055
|
+
const hasYaml = argv ? argv.some((a) => a === "--yaml" || a.startsWith("--yaml=")) : false;
|
|
13056
|
+
const mode = hasJson ? "json" : hasYaml ? "yaml" : "text";
|
|
12980
13057
|
const chainResult = await executeChain(input, { cdpEndpoint });
|
|
12981
|
-
if (
|
|
12982
|
-
|
|
12983
|
-
|
|
12984
|
-
|
|
12985
|
-
|
|
12986
|
-
|
|
12987
|
-
|
|
12988
|
-
|
|
12989
|
-
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
13058
|
+
if (mode === "json" || mode === "yaml") {
|
|
13059
|
+
outputEnvelope(
|
|
13060
|
+
{
|
|
13061
|
+
success: chainResult.success,
|
|
13062
|
+
data: {
|
|
13063
|
+
steps: chainResult.steps.map((s) => ({
|
|
13064
|
+
command: s.raw,
|
|
13065
|
+
success: s.success,
|
|
13066
|
+
data: s.data,
|
|
13067
|
+
duration: s.duration,
|
|
13068
|
+
...s.hookOutputs?.length ? { hooks: s.hookOutputs } : {}
|
|
13069
|
+
}))
|
|
13070
|
+
},
|
|
13071
|
+
duration: chainResult.totalDuration
|
|
13072
|
+
},
|
|
13073
|
+
{ command: "chain", totalSteps: chainResult.steps.length },
|
|
13074
|
+
mode
|
|
13075
|
+
);
|
|
12993
13076
|
} else {
|
|
12994
13077
|
printChainResult(chainResult);
|
|
12995
13078
|
}
|
|
@@ -13056,7 +13139,15 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
13056
13139
|
const sessionName = options.session || process.env.XBROWSER_SESSION || "default";
|
|
13057
13140
|
const cdpEndpoint = options.cdp || process.env.XBROWSER_CDP;
|
|
13058
13141
|
if (options.version || options.v && positional.length === 0) {
|
|
13059
|
-
|
|
13142
|
+
if (mode === "json") {
|
|
13143
|
+
outputEnvelope(
|
|
13144
|
+
{ success: true, data: { version, name: "@xbrowser/cli" } },
|
|
13145
|
+
{ command: "version" },
|
|
13146
|
+
mode
|
|
13147
|
+
);
|
|
13148
|
+
} else {
|
|
13149
|
+
console.log(`xbrowser v${version}`);
|
|
13150
|
+
}
|
|
13060
13151
|
return;
|
|
13061
13152
|
}
|
|
13062
13153
|
if (positional.length === 0) {
|
|
@@ -13252,18 +13343,23 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
13252
13343
|
if (isChainInput(fullInput)) {
|
|
13253
13344
|
const chainResult = await executeChain(fullInput, { cdpEndpoint, sessionName });
|
|
13254
13345
|
if (mode === "json" || mode === "yaml") {
|
|
13255
|
-
|
|
13256
|
-
|
|
13257
|
-
|
|
13258
|
-
|
|
13259
|
-
|
|
13260
|
-
|
|
13261
|
-
|
|
13262
|
-
|
|
13263
|
-
|
|
13264
|
-
|
|
13265
|
-
|
|
13266
|
-
|
|
13346
|
+
outputEnvelope(
|
|
13347
|
+
{
|
|
13348
|
+
success: chainResult.success,
|
|
13349
|
+
data: {
|
|
13350
|
+
steps: chainResult.steps.map((s) => ({
|
|
13351
|
+
command: s.raw,
|
|
13352
|
+
success: s.success,
|
|
13353
|
+
data: s.data,
|
|
13354
|
+
duration: s.duration
|
|
13355
|
+
})),
|
|
13356
|
+
...chainResult.stoppedReason ? { stoppedReason: chainResult.stoppedReason } : {}
|
|
13357
|
+
},
|
|
13358
|
+
duration: chainResult.totalDuration
|
|
13359
|
+
},
|
|
13360
|
+
{ command: "chain", totalSteps: chainResult.steps.length },
|
|
13361
|
+
mode
|
|
13362
|
+
);
|
|
13267
13363
|
if (!chainResult.success) throw new Error("Command failed");
|
|
13268
13364
|
return;
|
|
13269
13365
|
}
|
|
@@ -13408,6 +13504,17 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
|
|
|
13408
13504
|
session = await createSession(sessionName, void 0, cdpEndpoint ? { cdpEndpoint } : {});
|
|
13409
13505
|
}
|
|
13410
13506
|
}
|
|
13507
|
+
const cmdTabIndex = options.tab !== void 0 ? Number(options.tab) : void 0;
|
|
13508
|
+
if (cmdTabIndex !== void 0 && session?.context) {
|
|
13509
|
+
const pages = session.context.pages();
|
|
13510
|
+
if (cmdTabIndex >= 0 && cmdTabIndex < pages.length) {
|
|
13511
|
+
const targetPage = pages[cmdTabIndex];
|
|
13512
|
+
await targetPage.bringToFront().catch(() => {
|
|
13513
|
+
});
|
|
13514
|
+
const { setActivePage: setActivePage2 } = await import("./browser-TLIDFFEG.js");
|
|
13515
|
+
setActivePage2(session, targetPage);
|
|
13516
|
+
}
|
|
13517
|
+
}
|
|
13411
13518
|
const ctx = {
|
|
13412
13519
|
args: cmdArgsForPlugin,
|
|
13413
13520
|
options,
|
|
@@ -13485,22 +13592,17 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
|
|
|
13485
13592
|
const outputData = isCommandResult2(result) ? result.data : result && typeof result === "object" ? result.data ?? result : result;
|
|
13486
13593
|
const tips = isCommandResult2(result) ? result.tips : result && typeof result === "object" ? result.tips : void 0;
|
|
13487
13594
|
if (mode === "json" || mode === "yaml") {
|
|
13488
|
-
const
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
|
|
13495
|
-
|
|
13496
|
-
|
|
13497
|
-
|
|
13498
|
-
|
|
13499
|
-
}
|
|
13500
|
-
console.log(outputFormatter2.format(finalOutput, { mode, color: false, emoji: false }));
|
|
13501
|
-
if (tips?.length) {
|
|
13502
|
-
for (const tip of tips) console.error(`\u{1F4A1} ${typeof tip === "string" ? tip : tip.message}`);
|
|
13503
|
-
}
|
|
13595
|
+
const resultSuccess = isCommandResult2(result) ? result.success !== false : true;
|
|
13596
|
+
const resultMsg = isCommandResult2(result) ? result.message : void 0;
|
|
13597
|
+
const duration = Date.now() - cmdStart;
|
|
13598
|
+
const envelopeMeta = { command: `${command} ${subCommand}` };
|
|
13599
|
+
if (injectedViewerUrl) envelopeMeta.viewerUrl = injectedViewerUrl;
|
|
13600
|
+
if (hookOutputs.length > 0) envelopeMeta.hooks = hookOutputs;
|
|
13601
|
+
outputEnvelope(
|
|
13602
|
+
{ success: resultSuccess, data: outputData, message: resultMsg, tips, duration },
|
|
13603
|
+
envelopeMeta,
|
|
13604
|
+
mode
|
|
13605
|
+
);
|
|
13504
13606
|
} else {
|
|
13505
13607
|
console.log(outputFormatter2.format(outputData, { mode: "text", color: true, emoji: true }));
|
|
13506
13608
|
if (tips?.length) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xbrowser/cli",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.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": {
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"prepare": "husky"
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@dyyz1993/xcli-core": "^0.
|
|
87
|
+
"@dyyz1993/xcli-core": "^0.19.0",
|
|
88
88
|
"@types/react-syntax-highlighter": "^15.5.13",
|
|
89
89
|
"@types/turndown": "^5.0.6",
|
|
90
90
|
"cheerio": "^1.2.0",
|