@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/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SessionRecorder
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RMYEHTLS.js";
|
|
5
5
|
import {
|
|
6
6
|
addKnownIssue,
|
|
7
7
|
getKnowledgePath,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
resolveLaunchOpts,
|
|
26
26
|
saveSessionDiskMeta,
|
|
27
27
|
setActivePage
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-SJLRCE6N.js";
|
|
29
29
|
import "./chunk-TNEN6VQ2.js";
|
|
30
30
|
import {
|
|
31
31
|
forwardCommandLog,
|
|
@@ -7205,9 +7205,14 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7205
7205
|
const { _target: _u, ...rest } = params;
|
|
7206
7206
|
params = rest;
|
|
7207
7207
|
}
|
|
7208
|
+
const _tabIndex = params._tabIndex;
|
|
7209
|
+
if (_tabIndex !== void 0) {
|
|
7210
|
+
const { _tabIndex: _u, ...rest } = params;
|
|
7211
|
+
params = rest;
|
|
7212
|
+
}
|
|
7208
7213
|
let targetPageOverride = null;
|
|
7209
7214
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7210
|
-
const { findTargetPage } = await import("./browser-
|
|
7215
|
+
const { findTargetPage } = await import("./browser-XPKM344Y.js");
|
|
7211
7216
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7212
7217
|
if (!targetPageOverride) {
|
|
7213
7218
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -7279,6 +7284,16 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7279
7284
|
cliName: "xbrowser",
|
|
7280
7285
|
tips: new TipCollector2()
|
|
7281
7286
|
};
|
|
7287
|
+
if (_tabIndex !== void 0 && session?.context) {
|
|
7288
|
+
const pages = session.context.pages();
|
|
7289
|
+
if (_tabIndex >= 0 && _tabIndex < pages.length) {
|
|
7290
|
+
const targetPage = pages[_tabIndex];
|
|
7291
|
+
await targetPage.bringToFront().catch(() => {
|
|
7292
|
+
});
|
|
7293
|
+
setActivePage(session, targetPage);
|
|
7294
|
+
ctx.page = targetPage;
|
|
7295
|
+
}
|
|
7296
|
+
}
|
|
7282
7297
|
const start = Date.now();
|
|
7283
7298
|
if (session) {
|
|
7284
7299
|
streamCommandEvent(session.id, {
|
|
@@ -7307,7 +7322,17 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7307
7322
|
if (hooks.length > 0 && session?.page) {
|
|
7308
7323
|
await Promise.all(hooks.map((h) => h.onBeforeCommand?.({ page: session.page, command: commandName, params })));
|
|
7309
7324
|
}
|
|
7310
|
-
|
|
7325
|
+
let raw;
|
|
7326
|
+
const handlerPromise = command.handler(params, ctx);
|
|
7327
|
+
if (extraOpts?.timeout && extraOpts.timeout > 0) {
|
|
7328
|
+
const timeoutMs = extraOpts.timeout;
|
|
7329
|
+
const timeoutPromise = new Promise(
|
|
7330
|
+
(_, reject) => setTimeout(() => reject(new Error(`Command timed out after ${timeoutMs}ms`)), timeoutMs)
|
|
7331
|
+
);
|
|
7332
|
+
raw = await Promise.race([handlerPromise, timeoutPromise]);
|
|
7333
|
+
} else {
|
|
7334
|
+
raw = await handlerPromise;
|
|
7335
|
+
}
|
|
7311
7336
|
const end = Date.now();
|
|
7312
7337
|
const duration = end - start;
|
|
7313
7338
|
let hookOutputs;
|
|
@@ -7883,16 +7908,29 @@ var configBuiltin = {
|
|
|
7883
7908
|
execute: async (args, _options, _ctx) => {
|
|
7884
7909
|
const [subcommand, ...rest] = args;
|
|
7885
7910
|
if (!subcommand || subcommand === "list") {
|
|
7911
|
+
let flatten2 = function(obj, prefix = "") {
|
|
7912
|
+
const entries2 = [];
|
|
7913
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
7914
|
+
const fullKey = prefix ? `${prefix}.${k}` : k;
|
|
7915
|
+
if (v && typeof v === "object" && !Array.isArray(v)) {
|
|
7916
|
+
entries2.push(...flatten2(v, fullKey));
|
|
7917
|
+
} else {
|
|
7918
|
+
entries2.push({ key: fullKey, value: v });
|
|
7919
|
+
}
|
|
7920
|
+
}
|
|
7921
|
+
return entries2;
|
|
7922
|
+
};
|
|
7923
|
+
var flatten = flatten2;
|
|
7886
7924
|
const config = loadConfig();
|
|
7887
|
-
const
|
|
7888
|
-
if (
|
|
7925
|
+
const entries = flatten2(config);
|
|
7926
|
+
if (entries.length === 0) {
|
|
7889
7927
|
console.log("Configuration is empty");
|
|
7890
7928
|
return;
|
|
7891
7929
|
}
|
|
7892
7930
|
console.log("Configuration:");
|
|
7893
7931
|
console.log("");
|
|
7894
|
-
for (const
|
|
7895
|
-
console.log(` ${
|
|
7932
|
+
for (const { key, value } of entries) {
|
|
7933
|
+
console.log(` ${key} = ${value}`);
|
|
7896
7934
|
}
|
|
7897
7935
|
return;
|
|
7898
7936
|
}
|
|
@@ -8691,6 +8729,39 @@ function outputError(message) {
|
|
|
8691
8729
|
console.error(formatted);
|
|
8692
8730
|
process.exit(1);
|
|
8693
8731
|
}
|
|
8732
|
+
function outputEnvelope(result, meta, mode) {
|
|
8733
|
+
if (mode !== "json" && mode !== "yaml") {
|
|
8734
|
+
if (!result.success) {
|
|
8735
|
+
outputError(result.message || "Unknown error");
|
|
8736
|
+
return;
|
|
8737
|
+
}
|
|
8738
|
+
outputResult(result.data, mode);
|
|
8739
|
+
return;
|
|
8740
|
+
}
|
|
8741
|
+
const { command, ...extraMeta } = meta;
|
|
8742
|
+
const commandResult = {
|
|
8743
|
+
success: result.success,
|
|
8744
|
+
data: result.data,
|
|
8745
|
+
message: result.message,
|
|
8746
|
+
tips: [],
|
|
8747
|
+
meta: {
|
|
8748
|
+
duration: result.duration ?? 0,
|
|
8749
|
+
...extraMeta
|
|
8750
|
+
}
|
|
8751
|
+
};
|
|
8752
|
+
const formatted = outputFormatter.formatEnvelope(commandResult, {
|
|
8753
|
+
command,
|
|
8754
|
+
extraMeta,
|
|
8755
|
+
mode
|
|
8756
|
+
});
|
|
8757
|
+
console.log(formatted);
|
|
8758
|
+
if (result.tips?.length) {
|
|
8759
|
+
for (const tip of result.tips) {
|
|
8760
|
+
const text = typeof tip === "string" ? tip : tip.message;
|
|
8761
|
+
if (text) console.error(` \u{1F4A1} ${text}`);
|
|
8762
|
+
}
|
|
8763
|
+
}
|
|
8764
|
+
}
|
|
8694
8765
|
|
|
8695
8766
|
// src/builtins/plugin.ts
|
|
8696
8767
|
var pluginLoader2 = null;
|
|
@@ -10250,9 +10321,13 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
10250
10321
|
if (target) {
|
|
10251
10322
|
params = { ...params, _target: target };
|
|
10252
10323
|
}
|
|
10324
|
+
const tabIndex = options.tab;
|
|
10325
|
+
if (tabIndex !== void 0) {
|
|
10326
|
+
params = { ...params, _tabIndex: Number(tabIndex) };
|
|
10327
|
+
}
|
|
10253
10328
|
const result = cdpEndpoint ? await executeCommand(cmdName, params, sessionName, { cdpEndpoint }) : await executeCommand(cmdName, params, sessionName);
|
|
10254
10329
|
if (mode === "json" || mode === "yaml") {
|
|
10255
|
-
|
|
10330
|
+
outputEnvelope(result, { command: cmdName }, mode);
|
|
10256
10331
|
} else if (!result.success) {
|
|
10257
10332
|
outputError(result.message || "Command failed");
|
|
10258
10333
|
} else {
|
|
@@ -10312,7 +10387,7 @@ async function handleSession(args, options, mode, _cdpEndpoint) {
|
|
|
10312
10387
|
}
|
|
10313
10388
|
} catch {
|
|
10314
10389
|
}
|
|
10315
|
-
|
|
10390
|
+
outputEnvelope({ success: true, data: { closed: count, all: true } }, { command: "session close" }, mode);
|
|
10316
10391
|
} else {
|
|
10317
10392
|
const name = options.session || options.name || process.env.XBROWSER_SESSION || "default";
|
|
10318
10393
|
try {
|
|
@@ -10320,7 +10395,7 @@ async function handleSession(args, options, mode, _cdpEndpoint) {
|
|
|
10320
10395
|
} catch {
|
|
10321
10396
|
}
|
|
10322
10397
|
await closeSession(name);
|
|
10323
|
-
|
|
10398
|
+
outputEnvelope({ success: true, data: { name } }, { command: "session close" }, mode);
|
|
10324
10399
|
}
|
|
10325
10400
|
break;
|
|
10326
10401
|
}
|
|
@@ -10328,10 +10403,10 @@ async function handleSession(args, options, mode, _cdpEndpoint) {
|
|
|
10328
10403
|
case "ls": {
|
|
10329
10404
|
try {
|
|
10330
10405
|
const sessions2 = await forwardSessionList();
|
|
10331
|
-
|
|
10406
|
+
outputEnvelope({ success: true, data: { sessions: sessions2 } }, { command: "session list" }, mode);
|
|
10332
10407
|
} catch {
|
|
10333
10408
|
const sessions2 = await listSessions();
|
|
10334
|
-
|
|
10409
|
+
outputEnvelope({ success: true, data: { sessions: sessions2 } }, { command: "session list" }, mode);
|
|
10335
10410
|
}
|
|
10336
10411
|
break;
|
|
10337
10412
|
}
|
|
@@ -10346,7 +10421,7 @@ async function handleSession(args, options, mode, _cdpEndpoint) {
|
|
|
10346
10421
|
await stopDaemonProcess();
|
|
10347
10422
|
} catch {
|
|
10348
10423
|
}
|
|
10349
|
-
|
|
10424
|
+
outputEnvelope({ success: true, data: { name, killed: true, daemon: "stopped" } }, { command: "session kill" }, mode);
|
|
10350
10425
|
break;
|
|
10351
10426
|
}
|
|
10352
10427
|
case "kill-all": {
|
|
@@ -10365,7 +10440,7 @@ async function handleSession(args, options, mode, _cdpEndpoint) {
|
|
|
10365
10440
|
} catch {
|
|
10366
10441
|
}
|
|
10367
10442
|
const cleaned = cleanSessionFiles();
|
|
10368
|
-
|
|
10443
|
+
outputEnvelope({ success: true, data: { sessionsCleaned: cleaned, daemon: "killed" } }, { command: "session kill-all" }, mode);
|
|
10369
10444
|
break;
|
|
10370
10445
|
}
|
|
10371
10446
|
default:
|
|
@@ -10485,7 +10560,7 @@ async function handleSearch(args, options, mode) {
|
|
|
10485
10560
|
}
|
|
10486
10561
|
}
|
|
10487
10562
|
if (mode === "json") {
|
|
10488
|
-
|
|
10563
|
+
outputEnvelope({ success: true, data: { results, total: results.length } }, { command: "plugin search" }, mode);
|
|
10489
10564
|
} else {
|
|
10490
10565
|
if (results.length === 0) {
|
|
10491
10566
|
console.log("No plugins found");
|
|
@@ -10514,7 +10589,7 @@ async function handlePluginInfo(args, options, mode) {
|
|
|
10514
10589
|
if (pluginInfo) {
|
|
10515
10590
|
const d = pluginInfo;
|
|
10516
10591
|
if (mode === "json") {
|
|
10517
|
-
|
|
10592
|
+
outputEnvelope({ success: true, data: { source: "marketplace", ...d } }, { command: "plugin info" }, mode);
|
|
10518
10593
|
return;
|
|
10519
10594
|
}
|
|
10520
10595
|
console.log(`\u540D\u79F0: ${d.name || ""}`);
|
|
@@ -10540,7 +10615,7 @@ async function handlePluginInfo(args, options, mode) {
|
|
|
10540
10615
|
const pkg = latest && versions?.[latest];
|
|
10541
10616
|
if (pkg) {
|
|
10542
10617
|
if (mode === "json") {
|
|
10543
|
-
|
|
10618
|
+
outputEnvelope({ success: true, data: { source: "npm", name: pkg.name, version: latest, description: pkg.description } }, { command: "plugin info" }, mode);
|
|
10544
10619
|
return;
|
|
10545
10620
|
}
|
|
10546
10621
|
console.log(`\u540D\u79F0: ${pkg.name || ""}`);
|
|
@@ -10569,7 +10644,7 @@ async function handlePluginSchema(args, mode) {
|
|
|
10569
10644
|
return;
|
|
10570
10645
|
}
|
|
10571
10646
|
if (mode === "json") {
|
|
10572
|
-
|
|
10647
|
+
outputEnvelope({ success: true, data: contract }, { command: "plugin schema" }, mode);
|
|
10573
10648
|
return;
|
|
10574
10649
|
}
|
|
10575
10650
|
if ("commands" in contract) {
|
|
@@ -10647,8 +10722,9 @@ async function handlePlugin(args, options, mode) {
|
|
|
10647
10722
|
}
|
|
10648
10723
|
} catch {
|
|
10649
10724
|
}
|
|
10650
|
-
|
|
10651
|
-
{
|
|
10725
|
+
outputEnvelope(
|
|
10726
|
+
{ success: true, data: { name: result.name, source: result.source, path: result.path } },
|
|
10727
|
+
{ command: "plugin install" },
|
|
10652
10728
|
mode
|
|
10653
10729
|
);
|
|
10654
10730
|
break;
|
|
@@ -10667,7 +10743,7 @@ async function handlePlugin(args, options, mode) {
|
|
|
10667
10743
|
await loader.reloadPlugin(name);
|
|
10668
10744
|
} catch {
|
|
10669
10745
|
}
|
|
10670
|
-
|
|
10746
|
+
outputEnvelope({ success: true, data: { name } }, { command: "plugin uninstall" }, mode);
|
|
10671
10747
|
break;
|
|
10672
10748
|
}
|
|
10673
10749
|
case "list": {
|
|
@@ -10689,7 +10765,7 @@ async function handlePlugin(args, options, mode) {
|
|
|
10689
10765
|
};
|
|
10690
10766
|
});
|
|
10691
10767
|
if (mode === "json") {
|
|
10692
|
-
|
|
10768
|
+
outputEnvelope({ success: true, data: { plugins: enrichedPlugins } }, { command: "plugin list" }, mode);
|
|
10693
10769
|
} else {
|
|
10694
10770
|
if (enrichedPlugins.length === 0) {
|
|
10695
10771
|
console.log("No plugins installed");
|
|
@@ -10725,7 +10801,7 @@ Total: ${enrichedPlugins.length} plugins`);
|
|
|
10725
10801
|
} catch {
|
|
10726
10802
|
outputError(`Plugin "${name}" not found. Use 'xbrowser plugin list' to see installed plugins.`);
|
|
10727
10803
|
}
|
|
10728
|
-
|
|
10804
|
+
outputEnvelope({ success: true, data: { name } }, { command: "plugin reload" }, mode);
|
|
10729
10805
|
break;
|
|
10730
10806
|
}
|
|
10731
10807
|
case "search":
|
|
@@ -10757,24 +10833,22 @@ function handleDaemon(args, options, mode) {
|
|
|
10757
10833
|
case "start": {
|
|
10758
10834
|
const port = options.port ? Number(options.port) : 9224;
|
|
10759
10835
|
startDaemonProcess(port).then(
|
|
10760
|
-
(config) =>
|
|
10836
|
+
(config) => outputEnvelope({ success: true, data: { pid: config.pid, port: config.port } }, { command: "daemon start" }, mode)
|
|
10761
10837
|
).catch(
|
|
10762
10838
|
(e) => outputError(e instanceof Error ? e.message : String(e))
|
|
10763
10839
|
);
|
|
10764
10840
|
break;
|
|
10765
10841
|
}
|
|
10766
10842
|
case "stop": {
|
|
10767
|
-
stopDaemonProcess().then(() =>
|
|
10843
|
+
stopDaemonProcess().then(() => outputEnvelope({ success: true, data: {} }, { command: "daemon stop" }, mode)).catch(
|
|
10768
10844
|
(e) => outputError(e instanceof Error ? e.message : String(e))
|
|
10769
10845
|
);
|
|
10770
10846
|
break;
|
|
10771
10847
|
}
|
|
10772
10848
|
case "status": {
|
|
10773
10849
|
const status = getDaemonProcessStatus();
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
mode
|
|
10777
|
-
);
|
|
10850
|
+
const statusData = status.running ? { running: true, pid: status.pid, port: status.port } : { running: false };
|
|
10851
|
+
outputEnvelope({ success: true, data: statusData }, { command: "daemon status" }, mode);
|
|
10778
10852
|
break;
|
|
10779
10853
|
}
|
|
10780
10854
|
default:
|
|
@@ -11152,7 +11226,7 @@ async function handleFilter(args, _mode, options) {
|
|
|
11152
11226
|
console.log(` Original: ${result.originalCount}, After: ${result.filteredCount}, Removed: ${result.removed} (${result.percentage}%)`);
|
|
11153
11227
|
}
|
|
11154
11228
|
async function handleGeneratePlugin(sessionName, pluginName, outputDir) {
|
|
11155
|
-
const { SessionRecorder: SessionRecorder2 } = await import("./session-recorder-
|
|
11229
|
+
const { SessionRecorder: SessionRecorder2 } = await import("./session-recorder-33UKWCIR.js");
|
|
11156
11230
|
const { readSiteKnowledge: readSiteKnowledge2, toMarkdown } = await import("./site-knowledge-SYC6VCDB.js");
|
|
11157
11231
|
const { mkdirSync: mkdirSync10, writeFileSync: writeFileSync12 } = await import("fs");
|
|
11158
11232
|
const { join: join14 } = await import("path");
|
|
@@ -12499,7 +12573,8 @@ var KNOWN_GLOBAL_OPTIONS = /* @__PURE__ */ new Set([
|
|
|
12499
12573
|
"port",
|
|
12500
12574
|
"token",
|
|
12501
12575
|
"timeout",
|
|
12502
|
-
"headless"
|
|
12576
|
+
"headless",
|
|
12577
|
+
"tab"
|
|
12503
12578
|
]);
|
|
12504
12579
|
function showCommandHelp(siteName, cmd, siteConfig, mode) {
|
|
12505
12580
|
const c = cmd;
|
|
@@ -12653,20 +12728,28 @@ async function handleEvalMode(argv) {
|
|
|
12653
12728
|
}
|
|
12654
12729
|
async function handleChainInput(input, argv) {
|
|
12655
12730
|
const cdpEndpoint = argv ? extractCdpFromArgv(argv) : void 0;
|
|
12656
|
-
const
|
|
12731
|
+
const hasJson = argv ? argv.some((a) => a === "--json" || a.startsWith("--json=") || a.includes(" --json") || a.startsWith("--json")) || argv.includes("-j") : false;
|
|
12732
|
+
const hasYaml = argv ? argv.some((a) => a === "--yaml" || a.startsWith("--yaml=")) : false;
|
|
12733
|
+
const mode = hasJson ? "json" : hasYaml ? "yaml" : "text";
|
|
12657
12734
|
const chainResult = await executeChain(input, { cdpEndpoint });
|
|
12658
|
-
if (
|
|
12659
|
-
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12735
|
+
if (mode === "json" || mode === "yaml") {
|
|
12736
|
+
outputEnvelope(
|
|
12737
|
+
{
|
|
12738
|
+
success: chainResult.success,
|
|
12739
|
+
data: {
|
|
12740
|
+
steps: chainResult.steps.map((s) => ({
|
|
12741
|
+
command: s.raw,
|
|
12742
|
+
success: s.success,
|
|
12743
|
+
data: s.data,
|
|
12744
|
+
duration: s.duration,
|
|
12745
|
+
...s.hookOutputs?.length ? { hooks: s.hookOutputs } : {}
|
|
12746
|
+
}))
|
|
12747
|
+
},
|
|
12748
|
+
duration: chainResult.totalDuration
|
|
12749
|
+
},
|
|
12750
|
+
{ command: "chain", totalSteps: chainResult.steps.length },
|
|
12751
|
+
mode
|
|
12752
|
+
);
|
|
12670
12753
|
} else {
|
|
12671
12754
|
printChainResult(chainResult);
|
|
12672
12755
|
}
|
|
@@ -12733,7 +12816,15 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12733
12816
|
const sessionName = options.session || process.env.XBROWSER_SESSION || "default";
|
|
12734
12817
|
const cdpEndpoint = options.cdp || process.env.XBROWSER_CDP;
|
|
12735
12818
|
if (options.version || options.v && positional.length === 0) {
|
|
12736
|
-
|
|
12819
|
+
if (mode === "json") {
|
|
12820
|
+
outputEnvelope(
|
|
12821
|
+
{ success: true, data: { version, name: "@xbrowser/cli" } },
|
|
12822
|
+
{ command: "version" },
|
|
12823
|
+
mode
|
|
12824
|
+
);
|
|
12825
|
+
} else {
|
|
12826
|
+
console.log(`xbrowser v${version}`);
|
|
12827
|
+
}
|
|
12737
12828
|
return;
|
|
12738
12829
|
}
|
|
12739
12830
|
if (positional.length === 0) {
|
|
@@ -12929,18 +13020,23 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12929
13020
|
if (isChainInput(fullInput)) {
|
|
12930
13021
|
const chainResult = await executeChain(fullInput, { cdpEndpoint, sessionName });
|
|
12931
13022
|
if (mode === "json" || mode === "yaml") {
|
|
12932
|
-
|
|
12933
|
-
|
|
12934
|
-
|
|
12935
|
-
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
13023
|
+
outputEnvelope(
|
|
13024
|
+
{
|
|
13025
|
+
success: chainResult.success,
|
|
13026
|
+
data: {
|
|
13027
|
+
steps: chainResult.steps.map((s) => ({
|
|
13028
|
+
command: s.raw,
|
|
13029
|
+
success: s.success,
|
|
13030
|
+
data: s.data,
|
|
13031
|
+
duration: s.duration
|
|
13032
|
+
})),
|
|
13033
|
+
...chainResult.stoppedReason ? { stoppedReason: chainResult.stoppedReason } : {}
|
|
13034
|
+
},
|
|
13035
|
+
duration: chainResult.totalDuration
|
|
13036
|
+
},
|
|
13037
|
+
{ command: "chain", totalSteps: chainResult.steps.length },
|
|
13038
|
+
mode
|
|
13039
|
+
);
|
|
12944
13040
|
if (!chainResult.success) throw new Error("Command failed");
|
|
12945
13041
|
return;
|
|
12946
13042
|
}
|
|
@@ -13085,6 +13181,17 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
|
|
|
13085
13181
|
session = await createSession(sessionName, void 0, cdpEndpoint ? { cdpEndpoint } : {});
|
|
13086
13182
|
}
|
|
13087
13183
|
}
|
|
13184
|
+
const cmdTabIndex = options.tab !== void 0 ? Number(options.tab) : void 0;
|
|
13185
|
+
if (cmdTabIndex !== void 0 && session?.context) {
|
|
13186
|
+
const pages = session.context.pages();
|
|
13187
|
+
if (cmdTabIndex >= 0 && cmdTabIndex < pages.length) {
|
|
13188
|
+
const targetPage = pages[cmdTabIndex];
|
|
13189
|
+
await targetPage.bringToFront().catch(() => {
|
|
13190
|
+
});
|
|
13191
|
+
const { setActivePage: setActivePage2 } = await import("./browser-XPKM344Y.js");
|
|
13192
|
+
setActivePage2(session, targetPage);
|
|
13193
|
+
}
|
|
13194
|
+
}
|
|
13088
13195
|
const ctx = {
|
|
13089
13196
|
args: cmdArgsForPlugin,
|
|
13090
13197
|
options,
|
|
@@ -13162,22 +13269,17 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
|
|
|
13162
13269
|
const outputData = isCommandResult2(result) ? result.data : result && typeof result === "object" ? result.data ?? result : result;
|
|
13163
13270
|
const tips = isCommandResult2(result) ? result.tips : result && typeof result === "object" ? result.tips : void 0;
|
|
13164
13271
|
if (mode === "json" || mode === "yaml") {
|
|
13165
|
-
const
|
|
13166
|
-
|
|
13167
|
-
|
|
13168
|
-
|
|
13169
|
-
|
|
13170
|
-
|
|
13171
|
-
|
|
13172
|
-
|
|
13173
|
-
|
|
13174
|
-
|
|
13175
|
-
|
|
13176
|
-
}
|
|
13177
|
-
console.log(outputFormatter2.format(finalOutput, { mode, color: false, emoji: false }));
|
|
13178
|
-
if (tips?.length) {
|
|
13179
|
-
for (const tip of tips) console.error(`\u{1F4A1} ${typeof tip === "string" ? tip : tip.message}`);
|
|
13180
|
-
}
|
|
13272
|
+
const resultSuccess = isCommandResult2(result) ? result.success !== false : true;
|
|
13273
|
+
const resultMsg = isCommandResult2(result) ? result.message : void 0;
|
|
13274
|
+
const duration = Date.now() - cmdStart;
|
|
13275
|
+
const envelopeMeta = { command: `${command} ${subCommand}` };
|
|
13276
|
+
if (injectedViewerUrl) envelopeMeta.viewerUrl = injectedViewerUrl;
|
|
13277
|
+
if (hookOutputs.length > 0) envelopeMeta.hooks = hookOutputs;
|
|
13278
|
+
outputEnvelope(
|
|
13279
|
+
{ success: resultSuccess, data: outputData, message: resultMsg, tips, duration },
|
|
13280
|
+
envelopeMeta,
|
|
13281
|
+
mode
|
|
13282
|
+
);
|
|
13181
13283
|
} else {
|
|
13182
13284
|
console.log(outputFormatter2.format(outputData, { mode: "text", color: true, emoji: true }));
|
|
13183
13285
|
if (tips?.length) {
|
|
@@ -13359,7 +13461,7 @@ async function main() {
|
|
|
13359
13461
|
const command = process.argv[2];
|
|
13360
13462
|
const isLongRunning = command === "preview" || command === "serve";
|
|
13361
13463
|
if (!isLongRunning) {
|
|
13362
|
-
const { ensureProcessCanExit } = await import("./browser-
|
|
13464
|
+
const { ensureProcessCanExit } = await import("./browser-XPKM344Y.js");
|
|
13363
13465
|
await ensureProcessCanExit().catch(() => {
|
|
13364
13466
|
});
|
|
13365
13467
|
process.exit(exitCode);
|
package/dist/daemon-main.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-VEDJ5XSQ.js";
|
|
6
6
|
import {
|
|
7
7
|
SessionRecorder
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-FL6DOSWV.js";
|
|
9
9
|
import {
|
|
10
10
|
closeEphemeralContext,
|
|
11
11
|
closeSessionByName,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
resolveLaunchOpts,
|
|
22
22
|
saveSessionDiskMeta,
|
|
23
23
|
setActivePage
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-HXLMMSU3.js";
|
|
25
25
|
import "./chunk-VJNMAWPZ.js";
|
|
26
26
|
import "./chunk-TNEN6VQ2.js";
|
|
27
27
|
import {
|
|
@@ -6742,9 +6742,14 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
6742
6742
|
const { _target: _u, ...rest } = params;
|
|
6743
6743
|
params = rest;
|
|
6744
6744
|
}
|
|
6745
|
+
const _tabIndex = params._tabIndex;
|
|
6746
|
+
if (_tabIndex !== void 0) {
|
|
6747
|
+
const { _tabIndex: _u, ...rest } = params;
|
|
6748
|
+
params = rest;
|
|
6749
|
+
}
|
|
6745
6750
|
let targetPageOverride = null;
|
|
6746
6751
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
6747
|
-
const { findTargetPage } = await import("./browser-
|
|
6752
|
+
const { findTargetPage } = await import("./browser-LW2MDJE4.js");
|
|
6748
6753
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
6749
6754
|
if (!targetPageOverride) {
|
|
6750
6755
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -6816,6 +6821,16 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
6816
6821
|
cliName: "xbrowser",
|
|
6817
6822
|
tips: new TipCollector2()
|
|
6818
6823
|
};
|
|
6824
|
+
if (_tabIndex !== void 0 && session?.context) {
|
|
6825
|
+
const pages = session.context.pages();
|
|
6826
|
+
if (_tabIndex >= 0 && _tabIndex < pages.length) {
|
|
6827
|
+
const targetPage = pages[_tabIndex];
|
|
6828
|
+
await targetPage.bringToFront().catch(() => {
|
|
6829
|
+
});
|
|
6830
|
+
setActivePage(session, targetPage);
|
|
6831
|
+
ctx.page = targetPage;
|
|
6832
|
+
}
|
|
6833
|
+
}
|
|
6819
6834
|
const start = Date.now();
|
|
6820
6835
|
if (session) {
|
|
6821
6836
|
streamCommandEvent(session.id, {
|
|
@@ -6844,7 +6859,17 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
6844
6859
|
if (hooks.length > 0 && session?.page) {
|
|
6845
6860
|
await Promise.all(hooks.map((h) => h.onBeforeCommand?.({ page: session.page, command: commandName, params })));
|
|
6846
6861
|
}
|
|
6847
|
-
|
|
6862
|
+
let raw;
|
|
6863
|
+
const handlerPromise = command.handler(params, ctx);
|
|
6864
|
+
if (extraOpts?.timeout && extraOpts.timeout > 0) {
|
|
6865
|
+
const timeoutMs = extraOpts.timeout;
|
|
6866
|
+
const timeoutPromise = new Promise(
|
|
6867
|
+
(_, reject) => setTimeout(() => reject(new Error(`Command timed out after ${timeoutMs}ms`)), timeoutMs)
|
|
6868
|
+
);
|
|
6869
|
+
raw = await Promise.race([handlerPromise, timeoutPromise]);
|
|
6870
|
+
} else {
|
|
6871
|
+
raw = await handlerPromise;
|
|
6872
|
+
}
|
|
6848
6873
|
const end = Date.now();
|
|
6849
6874
|
const duration = end - start;
|
|
6850
6875
|
let hookOutputs;
|
package/dist/index.d.ts
CHANGED
|
@@ -737,6 +737,7 @@ declare function setWSServer(server: WSServer | null): void;
|
|
|
737
737
|
declare function executeCommand(commandName: string, params: Record<string, unknown>, sessionName?: string, extraOpts?: {
|
|
738
738
|
cdpEndpoint?: string;
|
|
739
739
|
skipCleanup?: boolean;
|
|
740
|
+
timeout?: number;
|
|
740
741
|
}): Promise<ExecutionResult>;
|
|
741
742
|
/**
|
|
742
743
|
* Execute a chain of browser commands parsed from a string expression.
|