@xbrowser/cli 1.25.0 → 1.25.2

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.
@@ -20,8 +20,8 @@ import {
20
20
  saveSessionDiskMeta,
21
21
  setActivePage,
22
22
  touchSession
23
- } from "./chunk-X735U7G7.js";
24
- import "./chunk-GYB5BOSP.js";
23
+ } from "./chunk-2EEAXSBA.js";
24
+ import "./chunk-R3F4K2SB.js";
25
25
  import "./chunk-MYH6FIBZ.js";
26
26
  import "./chunk-GDKLH7ZY.js";
27
27
  import "./chunk-KFQGP6VL.js";
@@ -20,10 +20,10 @@ import {
20
20
  saveSessionDiskMeta,
21
21
  setActivePage,
22
22
  touchSession
23
- } from "./chunk-ROAXLDV7.js";
24
- import "./chunk-BH3GIMWE.js";
23
+ } from "./chunk-ZOYM7QMS.js";
24
+ import "./chunk-CGNHGAIJ.js";
25
25
  import "./chunk-A7NEA4PA.js";
26
- import "./chunk-GYB5BOSP.js";
26
+ import "./chunk-R3F4K2SB.js";
27
27
  import "./chunk-MYH6FIBZ.js";
28
28
  import "./chunk-GDKLH7ZY.js";
29
29
  import "./chunk-KFQGP6VL.js";
@@ -20,9 +20,9 @@ import {
20
20
  saveSessionDiskMeta,
21
21
  setActivePage,
22
22
  touchSession
23
- } from "./chunk-PKXJST62.js";
24
- import "./chunk-UR3R5LWF.js";
25
- import "./chunk-GYB5BOSP.js";
23
+ } from "./chunk-NNI5RT4A.js";
24
+ import "./chunk-U6GFDVNI.js";
25
+ import "./chunk-R3F4K2SB.js";
26
26
  import "./chunk-MYH6FIBZ.js";
27
27
  import "./chunk-GDKLH7ZY.js";
28
28
  import "./chunk-WYETQ5C7.js";
@@ -14,8 +14,8 @@ import {
14
14
  scrollIntoView,
15
15
  waitForActionable,
16
16
  waitForNetworkIdle
17
- } from "./chunk-UR3R5LWF.js";
18
- import "./chunk-GYB5BOSP.js";
17
+ } from "./chunk-U6GFDVNI.js";
18
+ import "./chunk-R3F4K2SB.js";
19
19
  import {
20
20
  connectToCDP,
21
21
  findChrome,
@@ -14,9 +14,9 @@ import {
14
14
  scrollIntoView,
15
15
  waitForActionable,
16
16
  waitForNetworkIdle
17
- } from "./chunk-BH3GIMWE.js";
17
+ } from "./chunk-CGNHGAIJ.js";
18
18
  import "./chunk-A7NEA4PA.js";
19
- import "./chunk-GYB5BOSP.js";
19
+ import "./chunk-R3F4K2SB.js";
20
20
  import {
21
21
  connectToCDP,
22
22
  findChrome,
@@ -5,7 +5,7 @@ import {
5
5
  landingOffset,
6
6
  rand,
7
7
  typingDelay
8
- } from "./chunk-GYB5BOSP.js";
8
+ } from "./chunk-R3F4K2SB.js";
9
9
  import {
10
10
  connectToCDP,
11
11
  errMsg,
@@ -1844,6 +1844,23 @@ var XBPageImpl = class _XBPageImpl {
1844
1844
  );
1845
1845
  } catch {
1846
1846
  }
1847
+ try {
1848
+ const rawUa = await this.conn.send(
1849
+ "Runtime.evaluate",
1850
+ { expression: "navigator.userAgent", returnByValue: true },
1851
+ this.sessionId
1852
+ );
1853
+ const ua = rawUa?.value || "";
1854
+ const cleaned = ua.replace(/HeadlessChrome/g, "Chrome");
1855
+ if (cleaned !== ua) {
1856
+ await this.conn.send(
1857
+ "Network.setUserAgentOverride",
1858
+ { userAgent: cleaned },
1859
+ this.sessionId
1860
+ );
1861
+ }
1862
+ } catch {
1863
+ }
1847
1864
  }
1848
1865
  const result = await this.conn.send(
1849
1866
  "Page.navigate",
@@ -4951,7 +4968,7 @@ async function launch(options = {}) {
4951
4968
  const bv = await conn.send("Browser.getVersion");
4952
4969
  const m = bv.product.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)/);
4953
4970
  if (m && !options.stealthConfig?.uaChProfile) {
4954
- const { deriveUaChProfileForBinary } = await import("./stealth-2AA2FSNN.js");
4971
+ const { deriveUaChProfileForBinary } = await import("./stealth-QNSMIHQK.js");
4955
4972
  stealthOpts = { stealthConfig: { uaChProfile: deriveUaChProfileForBinary(m[0], m[1]) } };
4956
4973
  }
4957
4974
  } catch {
@@ -5,7 +5,7 @@ import {
5
5
  landingOffset,
6
6
  rand,
7
7
  typingDelay
8
- } from "./chunk-GYB5BOSP.js";
8
+ } from "./chunk-R3F4K2SB.js";
9
9
  import {
10
10
  connectToCDP,
11
11
  launchChrome
@@ -1849,6 +1849,23 @@ var XBPageImpl = class _XBPageImpl {
1849
1849
  );
1850
1850
  } catch {
1851
1851
  }
1852
+ try {
1853
+ const rawUa = await this.conn.send(
1854
+ "Runtime.evaluate",
1855
+ { expression: "navigator.userAgent", returnByValue: true },
1856
+ this.sessionId
1857
+ );
1858
+ const ua = rawUa?.value || "";
1859
+ const cleaned = ua.replace(/HeadlessChrome/g, "Chrome");
1860
+ if (cleaned !== ua) {
1861
+ await this.conn.send(
1862
+ "Network.setUserAgentOverride",
1863
+ { userAgent: cleaned },
1864
+ this.sessionId
1865
+ );
1866
+ }
1867
+ } catch {
1868
+ }
1852
1869
  }
1853
1870
  const result = await this.conn.send(
1854
1871
  "Page.navigate",
@@ -4896,7 +4913,7 @@ async function launch(options = {}) {
4896
4913
  const bv = await conn.send("Browser.getVersion");
4897
4914
  const m = bv.product.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)/);
4898
4915
  if (m && !options.stealthConfig?.uaChProfile) {
4899
- const { deriveUaChProfileForBinary } = await import("./stealth-JOXGV34D.js");
4916
+ const { deriveUaChProfileForBinary } = await import("./stealth-MHJNBJY7.js");
4900
4917
  stealthOpts = { stealthConfig: { uaChProfile: deriveUaChProfileForBinary(m[0], m[1]) } };
4901
4918
  }
4902
4919
  } catch {
@@ -9,7 +9,7 @@ import {
9
9
  landingOffset,
10
10
  rand,
11
11
  typingDelay
12
- } from "./chunk-GYB5BOSP.js";
12
+ } from "./chunk-R3F4K2SB.js";
13
13
  import {
14
14
  connectToCDP,
15
15
  launchChrome
@@ -1745,6 +1745,23 @@ var XBPageImpl = class _XBPageImpl {
1745
1745
  );
1746
1746
  } catch {
1747
1747
  }
1748
+ try {
1749
+ const rawUa = await this.conn.send(
1750
+ "Runtime.evaluate",
1751
+ { expression: "navigator.userAgent", returnByValue: true },
1752
+ this.sessionId
1753
+ );
1754
+ const ua = rawUa?.value || "";
1755
+ const cleaned = ua.replace(/HeadlessChrome/g, "Chrome");
1756
+ if (cleaned !== ua) {
1757
+ await this.conn.send(
1758
+ "Network.setUserAgentOverride",
1759
+ { userAgent: cleaned },
1760
+ this.sessionId
1761
+ );
1762
+ }
1763
+ } catch {
1764
+ }
1748
1765
  }
1749
1766
  const result = await this.conn.send(
1750
1767
  "Page.navigate",
@@ -4852,7 +4869,7 @@ async function launch(options = {}) {
4852
4869
  const bv = await conn.send("Browser.getVersion");
4853
4870
  const m = bv.product.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)/);
4854
4871
  if (m && !options.stealthConfig?.uaChProfile) {
4855
- const { deriveUaChProfileForBinary } = await import("./stealth-JOXGV34D.js");
4872
+ const { deriveUaChProfileForBinary } = await import("./stealth-MHJNBJY7.js");
4856
4873
  stealthOpts = { stealthConfig: { uaChProfile: deriveUaChProfileForBinary(m[0], m[1]) } };
4857
4874
  }
4858
4875
  } catch {
@@ -9,7 +9,7 @@ import {
9
9
  resolveLaunchOpts,
10
10
  saveSessionDiskMeta,
11
11
  setActivePage
12
- } from "./chunk-PKXJST62.js";
12
+ } from "./chunk-NNI5RT4A.js";
13
13
  import {
14
14
  detectAntiBot,
15
15
  formatDetectionMessage
@@ -24,7 +24,7 @@ import {
24
24
  rand,
25
25
  sleep,
26
26
  wheelDelta
27
- } from "./chunk-GYB5BOSP.js";
27
+ } from "./chunk-R3F4K2SB.js";
28
28
  import {
29
29
  errMsg
30
30
  } from "./chunk-GDKLH7ZY.js";
@@ -8636,7 +8636,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8636
8636
  }
8637
8637
  let targetPageOverride = null;
8638
8638
  if (_target && extraOpts?.cdpEndpoint) {
8639
- const { findTargetPage } = await import("./browser-DFM2SQDM.js");
8639
+ const { findTargetPage } = await import("./browser-L3TUDYY3.js");
8640
8640
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
8641
8641
  if (!targetPageOverride) {
8642
8642
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  launch
3
- } from "./chunk-UR3R5LWF.js";
3
+ } from "./chunk-U6GFDVNI.js";
4
4
  import {
5
5
  errMsg
6
6
  } from "./chunk-GDKLH7ZY.js";
@@ -20,12 +20,12 @@ import {
20
20
  resolveLaunchOpts,
21
21
  saveSessionDiskMeta,
22
22
  setActivePage
23
- } from "./chunk-X735U7G7.js";
23
+ } from "./chunk-2EEAXSBA.js";
24
24
  import {
25
25
  rand,
26
26
  sleep,
27
27
  wheelDelta
28
- } from "./chunk-GYB5BOSP.js";
28
+ } from "./chunk-R3F4K2SB.js";
29
29
  import {
30
30
  errMsg
31
31
  } from "./chunk-GDKLH7ZY.js";
@@ -273,6 +273,9 @@ function getCommand(name) {
273
273
  function getAllCommands() {
274
274
  return Array.from(registry.values());
275
275
  }
276
+ function getCommandNames() {
277
+ return Array.from(registry.keys());
278
+ }
276
279
 
277
280
  // src/utils/ssr-detect.ts
278
281
  var SSR_VARIABLE_TO_FRAMEWORK = {
@@ -8316,7 +8319,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8316
8319
  }
8317
8320
  let targetPageOverride = null;
8318
8321
  if (_target && extraOpts?.cdpEndpoint) {
8319
- const { findTargetPage } = await import("./browser-I3EZY3FL.js");
8322
+ const { findTargetPage } = await import("./browser-33QQWEDI.js");
8320
8323
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
8321
8324
  if (!targetPageOverride) {
8322
8325
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -8864,6 +8867,7 @@ export {
8864
8867
  createStubContext,
8865
8868
  getCommand,
8866
8869
  getAllCommands,
8870
+ getCommandNames,
8867
8871
  attachDetectAntiBot,
8868
8872
  readJsonFile,
8869
8873
  PluginMetadataParser,
@@ -270,6 +270,25 @@ function buildStealthInitScript(config = DEFAULT_STEALTH_CONFIG) {
270
270
  // —— 真实浏览器失焦/后台时 hasFocus=false
271
271
  // S172: 原型层覆写——实例赋值可被 Document.prototype.hasFocus.call(document) 逃逸
272
272
  ' Document.prototype.hasFocus=function(){return document.visibilityState==="visible";};',
273
+ // 4a. 渲染层声明一致性(2026-09-13 实测双模式四差异,修 dpr/color-gamut 两项):
274
+ // headless 默认 devicePixelRatio=1 / color-gamut=srgb,而真实 Mac Chrome 是
275
+ // 2 / p3 —— 声明(UA 说是 Mac)与渲染参数对不上即 headless 铁证。
276
+ // UA 含 "Macintosh" 时对齐 Retina 声明(dpr=2、p3);Windows/Linux 保持
277
+ // 1 / srgb(与主流真机一致)。login-bridge 扩展侧 L0 已有同款,此处对齐 driver 侧。
278
+ " try{",
279
+ ' var _uaIsMac=navigator.userAgent.indexOf("Macintosh")>=0;',
280
+ " if(_uaIsMac){",
281
+ ' Object.defineProperty(window,"devicePixelRatio",{get:function(){return 2;},configurable:true});',
282
+ " var _mq=window.matchMedia.bind(window);",
283
+ " window.matchMedia=function(q){",
284
+ " var m=_mq(q);",
285
+ ' if(typeof q==="string"&&q.indexOf("color-gamut")>=0&&q.indexOf("p3")>=0){',
286
+ ' Object.defineProperty(m,"matches",{get:function(){return true;},configurable:true});',
287
+ " }",
288
+ " return m;",
289
+ " };",
290
+ " }",
291
+ " }catch(e){}",
273
292
  // 4. Canvas/WebGL fingerprint: per-session stable noise (d20).
274
293
  // Headless software raster differs subtly from Chrome GPU raster —
275
294
  // toDataURL hashes fingerprint the rasterizer. Inject a stable
@@ -5,7 +5,7 @@ import {
5
5
  landingOffset,
6
6
  rand,
7
7
  typingDelay
8
- } from "./chunk-GYB5BOSP.js";
8
+ } from "./chunk-R3F4K2SB.js";
9
9
  import {
10
10
  connectToCDP,
11
11
  launchChrome
@@ -1846,6 +1846,23 @@ var XBPageImpl = class _XBPageImpl {
1846
1846
  );
1847
1847
  } catch {
1848
1848
  }
1849
+ try {
1850
+ const rawUa = await this.conn.send(
1851
+ "Runtime.evaluate",
1852
+ { expression: "navigator.userAgent", returnByValue: true },
1853
+ this.sessionId
1854
+ );
1855
+ const ua = rawUa?.value || "";
1856
+ const cleaned = ua.replace(/HeadlessChrome/g, "Chrome");
1857
+ if (cleaned !== ua) {
1858
+ await this.conn.send(
1859
+ "Network.setUserAgentOverride",
1860
+ { userAgent: cleaned },
1861
+ this.sessionId
1862
+ );
1863
+ }
1864
+ } catch {
1865
+ }
1849
1866
  }
1850
1867
  const result = await this.conn.send(
1851
1868
  "Page.navigate",
@@ -4001,7 +4018,7 @@ async function launch(options = {}) {
4001
4018
  const bv = await conn.send("Browser.getVersion");
4002
4019
  const m = bv.product.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)/);
4003
4020
  if (m && !options.stealthConfig?.uaChProfile) {
4004
- const { deriveUaChProfileForBinary } = await import("./stealth-JOXGV34D.js");
4021
+ const { deriveUaChProfileForBinary } = await import("./stealth-MHJNBJY7.js");
4005
4022
  stealthOpts = { stealthConfig: { uaChProfile: deriveUaChProfileForBinary(m[0], m[1]) } };
4006
4023
  }
4007
4024
  } catch {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createRuleEngine,
3
3
  launch
4
- } from "./chunk-BH3GIMWE.js";
4
+ } from "./chunk-CGNHGAIJ.js";
5
5
  import {
6
6
  errMsg
7
7
  } from "./chunk-GDKLH7ZY.js";
package/dist/cli.js CHANGED
@@ -10,13 +10,14 @@ import {
10
10
  executeCommand,
11
11
  getAllCommands,
12
12
  getCommand,
13
+ getCommandNames,
13
14
  getPluginLoader,
14
15
  getPluginStorage,
15
16
  isChainInput,
16
17
  loadHooks,
17
18
  parsePluginParams,
18
19
  readJsonFile
19
- } from "./chunk-SGALUO4Z.js";
20
+ } from "./chunk-PO27V5UH.js";
20
21
  import "./chunk-JKVUFP3G.js";
21
22
  import {
22
23
  forwardCommandLog,
@@ -80,8 +81,8 @@ import {
80
81
  findSession,
81
82
  getAllSessions,
82
83
  saveSessionDiskMeta
83
- } from "./chunk-X735U7G7.js";
84
- import "./chunk-GYB5BOSP.js";
84
+ } from "./chunk-2EEAXSBA.js";
85
+ import "./chunk-R3F4K2SB.js";
85
86
  import "./chunk-MYH6FIBZ.js";
86
87
  import {
87
88
  errMsg
@@ -2508,10 +2509,11 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
2508
2509
  }
2509
2510
  case "mouse": {
2510
2511
  const flatArgs = args.flatMap((a) => a.split(/\s+/).filter(Boolean));
2511
- const action = options.action || flatArgs.find((a) => ["move", "click", "dblclick", "down", "up"].includes(a));
2512
- const actionIdx = action ? flatArgs.indexOf(action) : -1;
2513
- const x = options.x !== void 0 ? Number(options.x) : actionIdx >= 0 && flatArgs[actionIdx + 1] ? Number(flatArgs[actionIdx + 1]) : void 0;
2514
- const y = options.y !== void 0 ? Number(options.y) : actionIdx >= 0 && flatArgs[actionIdx + 2] ? Number(flatArgs[actionIdx + 2]) : void 0;
2512
+ const argActionIdx = flatArgs.findIndex((a) => ["move", "click", "dblclick", "down", "up"].includes(a));
2513
+ const action = options.action || (argActionIdx >= 0 ? flatArgs[argActionIdx] : void 0);
2514
+ const coordArgs = options.action !== void 0 ? flatArgs : argActionIdx >= 0 ? flatArgs.slice(argActionIdx + 1) : flatArgs;
2515
+ const x = options.x !== void 0 ? Number(options.x) : coordArgs[0] !== void 0 ? Number(coordArgs[0]) : void 0;
2516
+ const y = options.y !== void 0 ? Number(options.y) : coordArgs[1] !== void 0 ? Number(coordArgs[1]) : void 0;
2515
2517
  if (!action || x === void 0 || y === void 0 || isNaN(x) || isNaN(y)) {
2516
2518
  outputError("Usage: xbrowser mouse <move|click|dblclick> <x> <y>\n xbrowser mouse --action <action> --x <x> --y <y>");
2517
2519
  }
@@ -5466,7 +5468,13 @@ function extractSessionNameFromArgv(argv) {
5466
5468
  async function handleEvalMode(argv) {
5467
5469
  const evalCommands = parseEvalFlags(argv);
5468
5470
  if (evalCommands.length === 0) return;
5469
- const chain = evalCommands.map((script) => `eval --script-b64 ${Buffer.from(script, "utf8").toString("base64url")}`).join(" ; ");
5471
+ const knownCommands = new Set(getCommandNames());
5472
+ const chainParts = evalCommands.map((value) => {
5473
+ const firstWord = value.trim().split(/\s+/)[0] || "";
5474
+ if (knownCommands.has(firstWord)) return value;
5475
+ return `eval --script-b64 ${Buffer.from(value, "utf8").toString("base64url")}`;
5476
+ });
5477
+ const chain = chainParts.join(" ; ");
5470
5478
  const cdpEndpoint = extractCdpFromArgv(argv);
5471
5479
  const sessionArgIdx = argv.indexOf("--session");
5472
5480
  const sessionName = sessionArgIdx >= 0 && argv[sessionArgIdx + 1] ? argv[sessionArgIdx + 1] : process.env.XBROWSER_SESSION || "default";
@@ -5556,6 +5564,8 @@ async function handleChainInput(input, argv) {
5556
5564
  }
5557
5565
  async function routeCommand(argvIn, stdinCommands) {
5558
5566
  let argv = argvIn;
5567
+ let chainTokenStart = -1;
5568
+ let chainTokenEnd = -1;
5559
5569
  process.exitCode = 0;
5560
5570
  try {
5561
5571
  if (stdinCommands && stdinCommands.length > 0) {
@@ -5605,6 +5615,8 @@ async function routeCommand(argvIn, stdinCommands) {
5605
5615
  const remainder = chainArg.substring(spaceIdx + 1);
5606
5616
  let remainderParts = remainder.split(/\s+/).filter(Boolean);
5607
5617
  remainderParts = remainderParts.flatMap((part) => part.split(";").filter(Boolean));
5618
+ chainTokenStart = chainArgIdx;
5619
+ chainTokenEnd = chainArgIdx + remainderParts.length;
5608
5620
  argv = [...argv.slice(0, chainArgIdx), possibleCmd, ...remainderParts, ...argv.slice(chainArgIdx + 1)];
5609
5621
  }
5610
5622
  }
@@ -5830,6 +5842,10 @@ async function routeCommand(argvIn, stdinCommands) {
5830
5842
  const globalFlagSet = /* @__PURE__ */ new Set(["--session", "--cdp", "--json", "--yaml", "--help", "-h", "--version", "--output", "-o"]);
5831
5843
  const cleanParts = [];
5832
5844
  for (let i = 0; i < argv.length; i++) {
5845
+ if (chainTokenStart >= 0 && i >= chainTokenStart && i <= chainTokenEnd) {
5846
+ cleanParts.push(argv[i]);
5847
+ continue;
5848
+ }
5833
5849
  if (globalFlagSet.has(argv[i])) continue;
5834
5850
  if (i > 0 && globalFlagSet.has(argv[i - 1]) && !argv[i].startsWith("-")) continue;
5835
5851
  if (argv[i].startsWith("--session=") || argv[i].startsWith("--cdp=")) continue;
@@ -6016,7 +6032,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
6016
6032
  const targetPage = pages[cmdTabIndex];
6017
6033
  await targetPage.bringToFront().catch(() => {
6018
6034
  });
6019
- const { setActivePage } = await import("./browser-I3EZY3FL.js");
6035
+ const { setActivePage } = await import("./browser-33QQWEDI.js");
6020
6036
  setActivePage(session, targetPage);
6021
6037
  }
6022
6038
  }
@@ -6281,7 +6297,7 @@ async function handleRemote(args, options, mode) {
6281
6297
  }
6282
6298
  }
6283
6299
  async function startMcpServer() {
6284
- const { startMcpStdio } = await import("./server-22WXTWK3.js");
6300
+ const { startMcpStdio } = await import("./server-EZJW6IHU.js");
6285
6301
  startMcpStdio();
6286
6302
  }
6287
6303
 
@@ -6300,7 +6316,7 @@ async function main() {
6300
6316
  const command = process.argv[2];
6301
6317
  const isLongRunning = command === "preview" || command === "serve" || command === "mcp";
6302
6318
  if (!isLongRunning) {
6303
- const { ensureProcessCanExit } = await import("./browser-I3EZY3FL.js");
6319
+ const { ensureProcessCanExit } = await import("./browser-33QQWEDI.js");
6304
6320
  await ensureProcessCanExit().catch(() => {
6305
6321
  });
6306
6322
  process.exit(process.exitCode || exitCode);
@@ -38,10 +38,10 @@ import {
38
38
  resolveLaunchOpts,
39
39
  saveSessionDiskMeta,
40
40
  setActivePage
41
- } from "./chunk-ROAXLDV7.js";
41
+ } from "./chunk-ZOYM7QMS.js";
42
42
  import {
43
43
  createRuleEngine
44
- } from "./chunk-BH3GIMWE.js";
44
+ } from "./chunk-CGNHGAIJ.js";
45
45
  import {
46
46
  queryJS
47
47
  } from "./chunk-A7NEA4PA.js";
@@ -49,7 +49,7 @@ import {
49
49
  rand,
50
50
  sleep,
51
51
  wheelDelta
52
- } from "./chunk-GYB5BOSP.js";
52
+ } from "./chunk-R3F4K2SB.js";
53
53
  import "./chunk-MYH6FIBZ.js";
54
54
  import {
55
55
  errMsg
@@ -7871,7 +7871,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7871
7871
  }
7872
7872
  let targetPageOverride = null;
7873
7873
  if (_target && extraOpts?.cdpEndpoint) {
7874
- const { findTargetPage } = await import("./browser-WCHMUN6H.js");
7874
+ const { findTargetPage } = await import("./browser-4LOJSMWV.js");
7875
7875
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
7876
7876
  if (!targetPageOverride) {
7877
7877
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -9711,7 +9711,7 @@ function createRPCHandler() {
9711
9711
  if (isNewFormat) {
9712
9712
  try {
9713
9713
  const replayErrors = [];
9714
- const { SessionReplayer } = await import("./session-replayer-PSAPQBZA.js");
9714
+ const { SessionReplayer } = await import("./session-replayer-PJIUH7KI.js");
9715
9715
  const replayer = new SessionReplayer({
9716
9716
  page: session.page,
9717
9717
  stepDelay: slowMo * 500,
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ import {
48
48
  splitCommand,
49
49
  waitForAIResponse,
50
50
  waitForPage
51
- } from "./chunk-I4WCDFZR.js";
51
+ } from "./chunk-DRKL2RFQ.js";
52
52
  import {
53
53
  SessionRecorder
54
54
  } from "./chunk-IR6C24P7.js";
@@ -63,7 +63,7 @@ import {
63
63
  getBrowser,
64
64
  resetForTesting,
65
65
  saveSessionDiskMeta
66
- } from "./chunk-PKXJST62.js";
66
+ } from "./chunk-NNI5RT4A.js";
67
67
  import "./chunk-JKVUFP3G.js";
68
68
  import {
69
69
  forwardCommandLog,
@@ -120,8 +120,8 @@ import {
120
120
  generateJSScript,
121
121
  generatePythonScript
122
122
  } from "./chunk-ETCO4SNK.js";
123
- import "./chunk-UR3R5LWF.js";
124
- import "./chunk-GYB5BOSP.js";
123
+ import "./chunk-U6GFDVNI.js";
124
+ import "./chunk-R3F4K2SB.js";
125
125
  import "./chunk-MYH6FIBZ.js";
126
126
  import {
127
127
  errMsg
@@ -2604,10 +2604,11 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
2604
2604
  }
2605
2605
  case "mouse": {
2606
2606
  const flatArgs = args.flatMap((a) => a.split(/\s+/).filter(Boolean));
2607
- const action = options.action || flatArgs.find((a) => ["move", "click", "dblclick", "down", "up"].includes(a));
2608
- const actionIdx = action ? flatArgs.indexOf(action) : -1;
2609
- const x = options.x !== void 0 ? Number(options.x) : actionIdx >= 0 && flatArgs[actionIdx + 1] ? Number(flatArgs[actionIdx + 1]) : void 0;
2610
- const y = options.y !== void 0 ? Number(options.y) : actionIdx >= 0 && flatArgs[actionIdx + 2] ? Number(flatArgs[actionIdx + 2]) : void 0;
2607
+ const argActionIdx = flatArgs.findIndex((a) => ["move", "click", "dblclick", "down", "up"].includes(a));
2608
+ const action = options.action || (argActionIdx >= 0 ? flatArgs[argActionIdx] : void 0);
2609
+ const coordArgs = options.action !== void 0 ? flatArgs : argActionIdx >= 0 ? flatArgs.slice(argActionIdx + 1) : flatArgs;
2610
+ const x = options.x !== void 0 ? Number(options.x) : coordArgs[0] !== void 0 ? Number(coordArgs[0]) : void 0;
2611
+ const y = options.y !== void 0 ? Number(options.y) : coordArgs[1] !== void 0 ? Number(coordArgs[1]) : void 0;
2611
2612
  if (!action || x === void 0 || y === void 0 || isNaN(x) || isNaN(y)) {
2612
2613
  outputError("Usage: xbrowser mouse <move|click|dblclick> <x> <y>\n xbrowser mouse --action <action> --x <x> --y <y>");
2613
2614
  }
@@ -5562,7 +5563,13 @@ function extractSessionNameFromArgv(argv) {
5562
5563
  async function handleEvalMode(argv) {
5563
5564
  const evalCommands = parseEvalFlags(argv);
5564
5565
  if (evalCommands.length === 0) return;
5565
- const chain = evalCommands.map((script) => `eval --script-b64 ${Buffer.from(script, "utf8").toString("base64url")}`).join(" ; ");
5566
+ const knownCommands = new Set(getCommandNames());
5567
+ const chainParts = evalCommands.map((value) => {
5568
+ const firstWord = value.trim().split(/\s+/)[0] || "";
5569
+ if (knownCommands.has(firstWord)) return value;
5570
+ return `eval --script-b64 ${Buffer.from(value, "utf8").toString("base64url")}`;
5571
+ });
5572
+ const chain = chainParts.join(" ; ");
5566
5573
  const cdpEndpoint = extractCdpFromArgv(argv);
5567
5574
  const sessionArgIdx = argv.indexOf("--session");
5568
5575
  const sessionName = sessionArgIdx >= 0 && argv[sessionArgIdx + 1] ? argv[sessionArgIdx + 1] : process.env.XBROWSER_SESSION || "default";
@@ -5652,6 +5659,8 @@ async function handleChainInput(input, argv) {
5652
5659
  }
5653
5660
  async function routeCommand(argvIn, stdinCommands) {
5654
5661
  let argv = argvIn;
5662
+ let chainTokenStart = -1;
5663
+ let chainTokenEnd = -1;
5655
5664
  process.exitCode = 0;
5656
5665
  try {
5657
5666
  if (stdinCommands && stdinCommands.length > 0) {
@@ -5701,6 +5710,8 @@ async function routeCommand(argvIn, stdinCommands) {
5701
5710
  const remainder = chainArg.substring(spaceIdx + 1);
5702
5711
  let remainderParts = remainder.split(/\s+/).filter(Boolean);
5703
5712
  remainderParts = remainderParts.flatMap((part) => part.split(";").filter(Boolean));
5713
+ chainTokenStart = chainArgIdx;
5714
+ chainTokenEnd = chainArgIdx + remainderParts.length;
5704
5715
  argv = [...argv.slice(0, chainArgIdx), possibleCmd, ...remainderParts, ...argv.slice(chainArgIdx + 1)];
5705
5716
  }
5706
5717
  }
@@ -5926,6 +5937,10 @@ async function routeCommand(argvIn, stdinCommands) {
5926
5937
  const globalFlagSet = /* @__PURE__ */ new Set(["--session", "--cdp", "--json", "--yaml", "--help", "-h", "--version", "--output", "-o"]);
5927
5938
  const cleanParts = [];
5928
5939
  for (let i = 0; i < argv.length; i++) {
5940
+ if (chainTokenStart >= 0 && i >= chainTokenStart && i <= chainTokenEnd) {
5941
+ cleanParts.push(argv[i]);
5942
+ continue;
5943
+ }
5929
5944
  if (globalFlagSet.has(argv[i])) continue;
5930
5945
  if (i > 0 && globalFlagSet.has(argv[i - 1]) && !argv[i].startsWith("-")) continue;
5931
5946
  if (argv[i].startsWith("--session=") || argv[i].startsWith("--cdp=")) continue;
@@ -6112,7 +6127,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
6112
6127
  const targetPage = pages[cmdTabIndex];
6113
6128
  await targetPage.bringToFront().catch(() => {
6114
6129
  });
6115
- const { setActivePage } = await import("./browser-DFM2SQDM.js");
6130
+ const { setActivePage } = await import("./browser-L3TUDYY3.js");
6116
6131
  setActivePage(session, targetPage);
6117
6132
  }
6118
6133
  }
@@ -6377,7 +6392,7 @@ async function handleRemote(args, options, mode) {
6377
6392
  }
6378
6393
  }
6379
6394
  async function startMcpServer() {
6380
- const { startMcpStdio } = await import("./server-L7IV24YL.js");
6395
+ const { startMcpStdio } = await import("./server-IBQGNDSB.js");
6381
6396
  startMcpStdio();
6382
6397
  }
6383
6398
 
@@ -9292,7 +9307,7 @@ var DataCollector = class {
9292
9307
  return results;
9293
9308
  }
9294
9309
  async createBrowserContext() {
9295
- const { launch } = await import("./cdp-driver-57QV7C5O.js");
9310
+ const { launch } = await import("./cdp-driver-5YVI5AIS.js");
9296
9311
  const { browser } = await launch({
9297
9312
  headless: true,
9298
9313
  args: ["--no-sandbox", "--disable-setuid-sandbox"]
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  executeChain,
3
3
  executeCommand
4
- } from "./chunk-SGALUO4Z.js";
4
+ } from "./chunk-PO27V5UH.js";
5
5
  import "./chunk-JKVUFP3G.js";
6
6
  import "./chunk-3OD76SUE.js";
7
7
  import "./chunk-ZTHE5RBZ.js";
8
8
  import "./chunk-Q2DFJQGS.js";
9
- import "./chunk-X735U7G7.js";
10
- import "./chunk-GYB5BOSP.js";
9
+ import "./chunk-2EEAXSBA.js";
10
+ import "./chunk-R3F4K2SB.js";
11
11
  import "./chunk-MYH6FIBZ.js";
12
12
  import "./chunk-GDKLH7ZY.js";
13
13
  import "./chunk-KFQGP6VL.js";
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  executeChain,
3
3
  executeCommand
4
- } from "./chunk-I4WCDFZR.js";
5
- import "./chunk-PKXJST62.js";
4
+ } from "./chunk-DRKL2RFQ.js";
5
+ import "./chunk-NNI5RT4A.js";
6
6
  import "./chunk-JKVUFP3G.js";
7
7
  import "./chunk-3OD76SUE.js";
8
8
  import "./chunk-ZTHE5RBZ.js";
9
9
  import "./chunk-Q2DFJQGS.js";
10
- import "./chunk-UR3R5LWF.js";
11
- import "./chunk-GYB5BOSP.js";
10
+ import "./chunk-U6GFDVNI.js";
11
+ import "./chunk-R3F4K2SB.js";
12
12
  import "./chunk-MYH6FIBZ.js";
13
13
  import "./chunk-GDKLH7ZY.js";
14
14
  import "./chunk-WYETQ5C7.js";
@@ -61,7 +61,7 @@ var SessionReplayer = class {
61
61
  if (this.opts.page) {
62
62
  this.page = this.opts.page;
63
63
  } else if (this.opts.cdpUrl) {
64
- const { launch } = await import("./cdp-driver-BFGFAVAN.js");
64
+ const { launch } = await import("./cdp-driver-BYW7WY7E.js");
65
65
  const { browser } = await launch({ cdpEndpoint: this.opts.cdpUrl });
66
66
  let contexts = browser.contexts();
67
67
  for (let i = 0; i < 10 && contexts.length === 0; i++) {
@@ -11,7 +11,7 @@ import {
11
11
  sleep,
12
12
  typingDelay,
13
13
  wheelDelta
14
- } from "./chunk-GYB5BOSP.js";
14
+ } from "./chunk-R3F4K2SB.js";
15
15
  import "./chunk-KFQGP6VL.js";
16
16
  export {
17
17
  DEFAULT_STEALTH_CONFIG,
@@ -11,7 +11,7 @@ import {
11
11
  sleep,
12
12
  typingDelay,
13
13
  wheelDelta
14
- } from "./chunk-GYB5BOSP.js";
14
+ } from "./chunk-R3F4K2SB.js";
15
15
  import "./chunk-3RG5ZIWI.js";
16
16
  export {
17
17
  DEFAULT_STEALTH_CONFIG,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xbrowser/cli",
3
- "version": "1.25.0",
3
+ "version": "1.25.2",
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": {