@xbrowser/cli 1.0.2 → 1.0.3

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/index.js CHANGED
@@ -25,7 +25,7 @@ import {
25
25
  killAllDaemonProcesses,
26
26
  startDaemonProcess,
27
27
  stopDaemonProcess
28
- } from "./chunk-Q4IGYTKR.js";
28
+ } from "./chunk-6WOSXSCQ.js";
29
29
  import {
30
30
  CaptchaDetector,
31
31
  HumanInteractionManager,
@@ -81,9 +81,12 @@ import {
81
81
  resolveLaunchOpts,
82
82
  saveSessionDiskMeta,
83
83
  setActivePage
84
- } from "./chunk-JPA2ZT2R.js";
85
- import "./chunk-PPG4D2EW.js";
86
- import "./chunk-BBMRDUYQ.js";
84
+ } from "./chunk-TWWOIJM7.js";
85
+ import "./chunk-N2JFPWMI.js";
86
+ import "./chunk-TNEN6VQ2.js";
87
+ import {
88
+ errMsg
89
+ } from "./chunk-GDKLH7ZY.js";
87
90
  import {
88
91
  CDPInterceptorProxy,
89
92
  advise,
@@ -97,7 +100,7 @@ import {
97
100
  mouseTrajectoryRule,
98
101
  networkAnomalyRule,
99
102
  pageLifecycleRule
100
- } from "./chunk-ZZ2TFWIV.js";
103
+ } from "./chunk-ABXMBNQ6.js";
101
104
  import {
102
105
  __require
103
106
  } from "./chunk-KFQGP6VL.js";
@@ -113,8 +116,8 @@ import {
113
116
  ok as ok25,
114
117
  fail as fail7,
115
118
  isCommandResult,
116
- CompositeStorage,
117
- TipCollector,
119
+ CompositeStorage as CompositeStorage2,
120
+ TipCollector as TipCollector2,
118
121
  normalizeTips as normalizeTips6,
119
122
  configureArchiveStore,
120
123
  appendCommandToArchive,
@@ -232,6 +235,67 @@ function parsePluginParams(args, schema, base = {}) {
232
235
  return result;
233
236
  }
234
237
 
238
+ // src/utils/stub-context.ts
239
+ import { TipCollector, CompositeStorage } from "@dyyz1993/xcli-core";
240
+ var CONFIG_DIR = __require("path").join(__require("os").homedir(), ".xbrowser");
241
+ var NoopSiteInstance = class {
242
+ name = "stub";
243
+ url = "";
244
+ config = { name: "stub" };
245
+ command() {
246
+ return this;
247
+ }
248
+ group() {
249
+ return this;
250
+ }
251
+ login() {
252
+ return this;
253
+ }
254
+ logout() {
255
+ return this;
256
+ }
257
+ async isLoggedIn() {
258
+ return true;
259
+ }
260
+ async requireLogin() {
261
+ }
262
+ getStorage() {
263
+ return new CompositeStorage("stub", CONFIG_DIR, "xbrowser");
264
+ }
265
+ getAllCommands() {
266
+ return [];
267
+ }
268
+ getCommand() {
269
+ return null;
270
+ }
271
+ getOriginalHandler() {
272
+ return void 0;
273
+ }
274
+ async executeLogin() {
275
+ }
276
+ async executeLogout() {
277
+ }
278
+ async restoreLogin() {
279
+ return false;
280
+ }
281
+ };
282
+ function createStubContext(pluginName) {
283
+ return {
284
+ args: [],
285
+ options: {},
286
+ cwd: process.cwd(),
287
+ storage: new CompositeStorage(pluginName, CONFIG_DIR, "xbrowser"),
288
+ output: { mode: "text", showTips: false, color: false, emoji: false },
289
+ error: (msg) => {
290
+ throw new Error(msg);
291
+ },
292
+ config: {},
293
+ site: new NoopSiteInstance(),
294
+ cliName: "xbrowser",
295
+ tips: new TipCollector()
296
+ };
297
+ }
298
+
235
299
  // src/commands/navigation.ts
236
300
  import { z } from "zod";
237
301
  import { ok } from "@dyyz1993/xcli-core";
@@ -282,7 +346,7 @@ async function detectSsr(page) {
282
346
  try {
283
347
  const result = await page.evaluate((vars) => {
284
348
  for (const varName of vars) {
285
- const value = window[varName];
349
+ const value = Reflect.get(window, varName);
286
350
  if (value != null && typeof value === "object") {
287
351
  const keys = Object.keys(value).slice(0, 10);
288
352
  return { variable: varName, keys };
@@ -1631,7 +1695,7 @@ var healthCheckCommand = registerCommand({
1631
1695
  issues.push({
1632
1696
  severity: "error",
1633
1697
  category: "links",
1634
- message: `Broken link (fetch error): ${href} \u2014 ${err.message || "unknown"}`
1698
+ message: `Broken link (fetch error): ${href} \u2014 ${errMsg(err) || "unknown"}`
1635
1699
  });
1636
1700
  }
1637
1701
  }
@@ -5007,7 +5071,7 @@ async function actOnPage(page, sessionId, input) {
5007
5071
  ref: normalizedRef,
5008
5072
  success: false,
5009
5073
  reason: "browser_error",
5010
- message: error.message,
5074
+ message: errMsg(error),
5011
5075
  stale,
5012
5076
  screenHash: hash,
5013
5077
  target: refMatch?.target
@@ -5091,7 +5155,7 @@ async function waitForPage(page, input) {
5091
5155
  matched: input.selector ? "selector" : input.text ? "text" : input.url ? "url" : input.load ? "load" : input.fn ? "fn" : "screenHashChanged",
5092
5156
  timeout,
5093
5157
  elapsed: Date.now() - startedAt,
5094
- message: error.message
5158
+ message: errMsg(error)
5095
5159
  };
5096
5160
  }
5097
5161
  return {
@@ -6026,11 +6090,11 @@ async function detectWebdriverExposure(page) {
6026
6090
  try {
6027
6091
  const webdriver = await page.evaluate(() => {
6028
6092
  return {
6029
- webdriver: window.navigator && window.navigator instanceof Object ? window.navigator.webdriver : void 0,
6093
+ webdriver: navigator.webdriver,
6030
6094
  webdriverScriptFn: !!window.__webdriver_script_fn,
6031
6095
  webdriverEvaluate: !!window.__webdriver_evaluate,
6032
6096
  chrome: !!window.chrome,
6033
- permissions: window.navigator && window.navigator instanceof Object ? window.navigator.permissions : void 0
6097
+ permissions: navigator.permissions
6034
6098
  };
6035
6099
  }).catch(() => null);
6036
6100
  if (!webdriver) {
@@ -6390,19 +6454,26 @@ var patched = false;
6390
6454
  function patchLoginRequired() {
6391
6455
  if (patched) return;
6392
6456
  patched = true;
6393
- const proto = SiteInstanceImpl.prototype;
6394
- const original = proto.command;
6395
- proto.command = function(name, cmd) {
6396
- const result = original.call(this, name, cmd);
6457
+ const target = SiteInstanceImpl.prototype;
6458
+ const originalCommand = target.command;
6459
+ const wrapped = function(...args) {
6460
+ const result = originalCommand.apply(this, args);
6461
+ const [name, cmd] = args;
6397
6462
  const loginRequired = cmd.loginRequired;
6398
6463
  if (loginRequired) {
6399
- const entry = this.commands.get(name);
6464
+ const commands = this.commands;
6465
+ const entry = commands?.get(name);
6400
6466
  if (entry) {
6401
6467
  entry.loginRequired = loginRequired;
6402
6468
  }
6403
6469
  }
6404
6470
  return result;
6405
6471
  };
6472
+ Object.defineProperty(target, "command", {
6473
+ value: wrapped,
6474
+ writable: true,
6475
+ configurable: true
6476
+ });
6406
6477
  }
6407
6478
 
6408
6479
  // src/plugin/loader.ts
@@ -7096,15 +7167,14 @@ var HOOK_REGISTRY = {
7096
7167
  recorder: {
7097
7168
  name: "recorder",
7098
7169
  onAfterCommand: async (ctx) => {
7099
- const ctxAny = ctx;
7100
- const logs = ctxAny.__commandLogs || [];
7170
+ const logs = ("__commandLogs" in ctx ? ctx.__commandLogs : void 0) || [];
7101
7171
  logs.push({
7102
7172
  timestamp: Date.now(),
7103
7173
  command: ctx.command,
7104
7174
  params: JSON.parse(JSON.stringify(ctx.params)),
7105
7175
  duration: ctx.duration
7106
7176
  });
7107
- ctxAny.__commandLogs = logs;
7177
+ Reflect.set(ctx, "__commandLogs", logs);
7108
7178
  return void 0;
7109
7179
  }
7110
7180
  }
@@ -7136,11 +7206,11 @@ import { homedir as homedir5 } from "os";
7136
7206
  import { join as join5 } from "path";
7137
7207
  var NAVIGATION_COMMANDS = /* @__PURE__ */ new Set(["goto", "back", "forward", "refresh"]);
7138
7208
  var snapshotHintShown = /* @__PURE__ */ new WeakSet();
7139
- var CONFIG_DIR = join5(homedir5(), ".xbrowser");
7209
+ var CONFIG_DIR2 = join5(homedir5(), ".xbrowser");
7140
7210
  var storageCache = /* @__PURE__ */ new Map();
7141
7211
  function getPluginStorage(pluginName) {
7142
7212
  if (!storageCache.has(pluginName)) {
7143
- storageCache.set(pluginName, new CompositeStorage(pluginName, CONFIG_DIR, "xbrowser"));
7213
+ storageCache.set(pluginName, new CompositeStorage2(pluginName, CONFIG_DIR2, "xbrowser"));
7144
7214
  }
7145
7215
  return storageCache.get(pluginName);
7146
7216
  }
@@ -7208,7 +7278,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7208
7278
  }
7209
7279
  let targetPageOverride = null;
7210
7280
  if (_target && extraOpts?.cdpEndpoint) {
7211
- const { findTargetPage } = await import("./browser-ZJOZB5CR.js");
7281
+ const { findTargetPage } = await import("./browser-IUJXXNBT.js");
7212
7282
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
7213
7283
  if (!targetPageOverride) {
7214
7284
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -7225,7 +7295,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7225
7295
  params = result.data;
7226
7296
  }
7227
7297
  if (command.scope !== "cli" && !process.env.XBROWSER_DAEMON_WORKER) {
7228
- const { forwardExec } = await import("./daemon-client-UZZEHHIV.js");
7298
+ const { forwardExec } = await import("./daemon-client-3JOKX2L2.js");
7229
7299
  const result = await forwardExec(commandName, params, sessionName, extraOpts?.cdpEndpoint);
7230
7300
  if (result) return result;
7231
7301
  }
@@ -7276,9 +7346,9 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7276
7346
  throw new Error(msg);
7277
7347
  },
7278
7348
  config: {},
7279
- site: {},
7349
+ site: new NoopSiteInstance(),
7280
7350
  cliName: "xbrowser",
7281
- tips: new TipCollector()
7351
+ tips: new TipCollector2()
7282
7352
  };
7283
7353
  const start = Date.now();
7284
7354
  if (session) {
@@ -7391,7 +7461,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7391
7461
  } catch (err) {
7392
7462
  const end = Date.now();
7393
7463
  const duration = end - start;
7394
- const errorMessage = err.message;
7464
+ const errorMessage = errMsg(err);
7395
7465
  if (session) {
7396
7466
  streamCommandEvent(session.id, {
7397
7467
  sessionId: session.id,
@@ -7504,7 +7574,7 @@ async function executeChain(input, options) {
7504
7574
  config: {},
7505
7575
  site,
7506
7576
  cliName: "xbrowser",
7507
- tips: new TipCollector()
7577
+ tips: new TipCollector2()
7508
7578
  };
7509
7579
  const start2 = Date.now();
7510
7580
  try {
@@ -7591,7 +7661,7 @@ async function executeChain(input, options) {
7591
7661
  }
7592
7662
  } catch (err) {
7593
7663
  const duration2 = Date.now() - start2;
7594
- const errorMessage = err.message;
7664
+ const errorMessage = errMsg(err);
7595
7665
  recordArchive(session.id, sessionName, {
7596
7666
  step: results.length,
7597
7667
  command: `${cmdName} ${subCommand}`,
@@ -7731,7 +7801,12 @@ var BROWSER_SCOPE = {
7731
7801
  };
7732
7802
 
7733
7803
  // src/router.ts
7734
- import { parseArgs, outputFormatter as outputFormatter2, isCommandResult as isCommandResult2, helpGenerator as helpGenerator2, TipCollector as TipCollector2, normalizeTips as normalizeTips7, tip as makeTip } from "@dyyz1993/xcli-core";
7804
+ import { parseArgs, outputFormatter as outputFormatter2, isCommandResult as isCommandResult2, helpGenerator as helpGenerator2, TipCollector as TipCollector3, normalizeTips as normalizeTips7, tip as makeTip } from "@dyyz1993/xcli-core";
7805
+
7806
+ // src/utils/zod-internal.ts
7807
+ function asZodSchema(value) {
7808
+ return value;
7809
+ }
7735
7810
 
7736
7811
  // src/session/session-client.ts
7737
7812
  function sessionToInfo(s) {
@@ -8004,7 +8079,8 @@ async function ensureProxyFetch() {
8004
8079
  const body = init?.body;
8005
8080
  if (body instanceof globalThis.FormData && !(body instanceof UFormData)) {
8006
8081
  const ufd = new UFormData();
8007
- body.forEach((value, key) => {
8082
+ const domFormData = body;
8083
+ domFormData.forEach((value, key) => {
8008
8084
  if (value instanceof Blob) {
8009
8085
  ufd.append(key, value, value.name || "file");
8010
8086
  } else {
@@ -8919,7 +8995,7 @@ async function searchFromMarketplacePlugin(options, loader) {
8919
8995
  site: options.site,
8920
8996
  limit: options.limit
8921
8997
  },
8922
- {}
8998
+ createStubContext("marketplace")
8923
8999
  );
8924
9000
  const items = extractItems(result);
8925
9001
  return items.map((item) => ({
@@ -9700,16 +9776,16 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
9700
9776
  if (cmdDef) {
9701
9777
  if (mode === "json") {
9702
9778
  const paramsList = [];
9703
- const schema = cmdDef.parameters;
9779
+ const schema = asZodSchema(cmdDef.parameters);
9704
9780
  const shape = schema?.shape ?? schema?._def?.shape;
9705
9781
  if (shape) {
9706
9782
  for (const [key, value] of Object.entries(shape)) {
9707
- const fieldSchema = value;
9783
+ const fieldSchema = asZodSchema(value);
9708
9784
  const fieldDef = fieldSchema._def;
9709
9785
  const description = fieldSchema.description || fieldDef?.description || "";
9710
9786
  const typeName = fieldDef?.typeName || "";
9711
9787
  const isOptional = typeName === "ZodOptional" || typeof fieldSchema.isOptional === "function" && fieldSchema.isOptional();
9712
- const innerType = fieldDef?.innerType;
9788
+ const innerType = asZodSchema(fieldDef?.innerType);
9713
9789
  const innerTypeName = innerType?._def ? innerType._def.typeName : typeName;
9714
9790
  let type = "unknown";
9715
9791
  if (innerTypeName === "ZodString" || typeName === "ZodString") type = "string";
@@ -10119,8 +10195,7 @@ async function buildRuntimePluginInfo() {
10119
10195
  const cmds = site.getAllCommands();
10120
10196
  const commandNames = cmds.map((c) => c.name);
10121
10197
  if (commandNames.length === 0) continue;
10122
- const anySite = site;
10123
- const hasLoginHandler = typeof anySite.hasLoginCommand === "function" && anySite.hasLoginCommand();
10198
+ const hasLoginHandler = "hasLoginCommand" in site && typeof site.hasLoginCommand === "function" && site.hasLoginCommand();
10124
10199
  const configRequiresLogin = !!site.config.requiresLogin;
10125
10200
  const hasLogin = hasLoginHandler || configRequiresLogin;
10126
10201
  let loggedIn = null;
@@ -10170,7 +10245,7 @@ async function searchFromMarketplacePlugin2(options, loader) {
10170
10245
  site: options.site,
10171
10246
  limit: options.limit
10172
10247
  },
10173
- {}
10248
+ createStubContext("marketplace")
10174
10249
  );
10175
10250
  const items = extractItems2(result);
10176
10251
  return items.map((item) => ({ ...item, source: "marketplace" }));
@@ -10185,7 +10260,7 @@ async function infoFromMarketplacePlugin(slug, loader) {
10185
10260
  const infoCmd = marketplaceSite.getCommand("info");
10186
10261
  if (!infoCmd) return null;
10187
10262
  try {
10188
- const result = await infoCmd.handler({ slug }, {});
10263
+ const result = await infoCmd.handler({ slug }, createStubContext("marketplace"));
10189
10264
  if (!result || typeof result !== "object") return null;
10190
10265
  const r = result;
10191
10266
  let plugin = null;
@@ -10293,7 +10368,7 @@ async function handlePluginInfo(args, options, mode) {
10293
10368
  }
10294
10369
  console.error(`\u63D2\u4EF6 '${slug}' \u672A\u627E\u5230`);
10295
10370
  } catch (err) {
10296
- console.error("\u67E5\u8BE2\u5931\u8D25:", err.message);
10371
+ console.error("\u67E5\u8BE2\u5931\u8D25:", errMsg(err));
10297
10372
  }
10298
10373
  }
10299
10374
  async function handlePluginSchema(args, mode) {
@@ -10984,9 +11059,9 @@ interface XBPage {
10984
11059
  }
10985
11060
 
10986
11061
  function ensurePage(ctx: CommandContext): XBPage {
10987
- const page = (ctx as Record<string, unknown>).page;
11062
+ const page = 'page' in ctx ? (ctx as Record<string, unknown>).page : undefined;
10988
11063
  if (!page) throw new Error('No active page. Start a session first.');
10989
- return page as unknown as XBPage;
11064
+ return page as XBPage;
10990
11065
  }
10991
11066
 
10992
11067
  export default createSite({
@@ -11019,7 +11094,7 @@ async function handleRun(filePath, options) {
11019
11094
  try {
11020
11095
  commands = readCommandFile(filePath);
11021
11096
  } catch (e) {
11022
- outputError(`Failed to read file '${filePath}': ${e.message}`);
11097
+ outputError(`Failed to read file '${filePath}': ${errMsg(e)}`);
11023
11098
  return;
11024
11099
  }
11025
11100
  if (commands.length === 0) {
@@ -11375,7 +11450,7 @@ async function handleNetCommand(args, options, mode, sessionName) {
11375
11450
  outputError(`Unknown net sub-command: ${subCommand}. Use: list, clear, top, log, around, analyze, curl, replay, inspect, like, dislike, export`);
11376
11451
  }
11377
11452
  } catch (err) {
11378
- outputError(err.message || "Network command failed");
11453
+ outputError(errMsg(err) || "Network command failed");
11379
11454
  }
11380
11455
  }
11381
11456
 
@@ -11900,7 +11975,7 @@ async function createSessionHandler(req) {
11900
11975
  createdAt: session.createdAt
11901
11976
  });
11902
11977
  } catch (err) {
11903
- return errorResponse(500, "INTERNAL_ERROR", err.message);
11978
+ return errorResponse(500, "INTERNAL_ERROR", errMsg(err));
11904
11979
  }
11905
11980
  }
11906
11981
  async function closeSession2(req) {
@@ -11995,7 +12070,7 @@ async function route(method, url, headers, body) {
11995
12070
  try {
11996
12071
  return await match.route.handler(req);
11997
12072
  } catch (err) {
11998
- return errorResponse(500, "INTERNAL_ERROR", err.message);
12073
+ return errorResponse(500, "INTERNAL_ERROR", errMsg(err));
11999
12074
  }
12000
12075
  }
12001
12076
  async function handleRequest(req, res, validateAuthFn) {
@@ -12153,8 +12228,9 @@ function showCommandHelp(siteName, cmd, siteConfig, mode) {
12153
12228
  if (mode === "json") {
12154
12229
  const paramsList = [];
12155
12230
  if (c.parameters) {
12156
- const def = c.parameters._def;
12157
- const shape = def.shape?.();
12231
+ const def = asZodSchema(c.parameters)._def;
12232
+ const rawShape = def?.shape;
12233
+ const shape = typeof rawShape === "function" ? rawShape() : rawShape;
12158
12234
  if (shape) {
12159
12235
  for (const [key, value] of Object.entries(shape)) {
12160
12236
  const info = extractZodFieldInfo(value);
@@ -12381,16 +12457,16 @@ async function routeCommand(argv, stdinCommands) {
12381
12457
  if (builtinCmd) {
12382
12458
  if (mode === "json") {
12383
12459
  const paramsList = [];
12384
- const schema = builtinCmd.parameters;
12460
+ const schema = asZodSchema(builtinCmd.parameters);
12385
12461
  const shape = schema?.shape ?? schema?._def?.shape;
12386
12462
  if (shape) {
12387
12463
  for (const [key, value] of Object.entries(shape)) {
12388
- const fieldSchema = value;
12464
+ const fieldSchema = asZodSchema(value);
12389
12465
  const fieldDef = fieldSchema._def;
12390
12466
  const description = fieldSchema.description || fieldDef?.description || "";
12391
12467
  const typeName = fieldDef?.typeName || "";
12392
12468
  const isOptional = typeName === "ZodOptional" || typeof fieldSchema.isOptional === "function" && fieldSchema.isOptional();
12393
- const innerType = fieldDef?.innerType;
12469
+ const innerType = asZodSchema(fieldDef?.innerType);
12394
12470
  const innerTypeName = innerType?._def ? innerType._def.typeName : typeName;
12395
12471
  let type = "unknown";
12396
12472
  if (innerTypeName === "ZodString" || typeName === "ZodString") type = "string";
@@ -12565,7 +12641,7 @@ Run "xbrowser ${command} --help" to see available commands.`
12565
12641
  const rawPluginArgs = subCmdIdx >= 0 ? argv.slice(subCmdIdx + 1) : [];
12566
12642
  const params = parsePluginParams(rawPluginArgs, cmdEntry.parameters);
12567
12643
  if (cmdEntry.parameters) {
12568
- const schemaAny = cmdEntry.parameters;
12644
+ const schemaAny = asZodSchema(cmdEntry.parameters);
12569
12645
  const def = schemaAny._def;
12570
12646
  const shapeOrFn = def?.shape ?? schemaAny.shape;
12571
12647
  const shapeObj = typeof shapeOrFn === "function" ? shapeOrFn() : shapeOrFn;
@@ -12589,10 +12665,10 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
12589
12665
  }
12590
12666
  const needsBrowser = cmdEntry.scope === "page" || cmdEntry.scope === "browser";
12591
12667
  if (needsBrowser && !process.env.XBROWSER_DAEMON_WORKER) {
12592
- const { forwardExec } = await import("./daemon-client-UZZEHHIV.js");
12668
+ const { forwardExec } = await import("./daemon-client-3JOKX2L2.js");
12593
12669
  const userTimeout = typeof params.timeout === "number" && params.timeout > 0 ? params.timeout * 1e3 + 3e4 : void 0;
12594
12670
  const result = await forwardExec(`${command}.${subCommand}`, params, sessionName, cdpEndpoint, userTimeout);
12595
- const resultData = result && typeof result === "object" ? result.data : void 0;
12671
+ const resultData = result && typeof result === "object" && "data" in result ? result.data : void 0;
12596
12672
  if (result && result.success === false && resultData?.code === "LOGIN_REQUIRED") {
12597
12673
  outputLoginRequired(result, mode);
12598
12674
  return;
@@ -12641,7 +12717,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
12641
12717
  waitForHuman: async (_opts) => {
12642
12718
  return { solved: false, timedOut: true };
12643
12719
  },
12644
- tips: new TipCollector2()
12720
+ tips: new TipCollector3()
12645
12721
  };
12646
12722
  try {
12647
12723
  const cmdStart = Date.now();
@@ -13084,7 +13160,7 @@ var PlaybackEngine = class _PlaybackEngine {
13084
13160
  const content = fs4.readFileSync(filePath, "utf-8");
13085
13161
  const raw = filePath.endsWith(".json") ? JSON.parse(content) : yaml2.parse(content);
13086
13162
  let recording;
13087
- const checkpoints = raw.checkpoints || [];
13163
+ const checkpoints = "checkpoints" in raw ? raw.checkpoints : [];
13088
13164
  if (raw.events && raw.events.length > 0) {
13089
13165
  recording = raw;
13090
13166
  } else if (raw.actions && raw.actions.length > 0) {
@@ -13157,7 +13233,7 @@ var PlaybackEngine = class _PlaybackEngine {
13157
13233
  errors.push({
13158
13234
  eventIndex: i,
13159
13235
  event,
13160
- error: err.message
13236
+ error: errMsg(err)
13161
13237
  });
13162
13238
  if (stopOnError) break;
13163
13239
  }
@@ -13594,14 +13670,13 @@ var ElementMonitor = class {
13594
13670
  document.addEventListener("focusin", (e) => {
13595
13671
  const el = e.target;
13596
13672
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.contentEditable === "true") {
13597
- const w = window;
13598
- w.__xb_focus_seq = (w.__xb_focus_seq || 0) + 1;
13673
+ window.__xb_focus_seq = (window.__xb_focus_seq || 0) + 1;
13599
13674
  const info = {
13600
13675
  selector: "",
13601
13676
  tag: el.tagName,
13602
13677
  value: el.value || "",
13603
13678
  placeholder: el.placeholder || "",
13604
- seq: w.__xb_focus_seq
13679
+ seq: window.__xb_focus_seq
13605
13680
  };
13606
13681
  if (el.id) info.selector = "#" + el.id;
13607
13682
  else if (el.getAttribute("name")) info.selector = '[name="' + el.getAttribute("name") + '"]';
@@ -13609,7 +13684,7 @@ var ElementMonitor = class {
13609
13684
  if (el.tagName === "INPUT" && el.type === "file") {
13610
13685
  info.isFileInput = true;
13611
13686
  }
13612
- w.__xb_last_focused = info;
13687
+ window.__xb_last_focused = info;
13613
13688
  }
13614
13689
  }, true);
13615
13690
  document.addEventListener("focusout", () => {
@@ -15683,7 +15758,7 @@ var DataCollector = class {
15683
15758
  return results;
15684
15759
  }
15685
15760
  async createBrowserContext() {
15686
- const { launch } = await import("./cdp-driver-TOPYJIFL.js");
15761
+ const { launch } = await import("./cdp-driver-D6WMSMWX.js");
15687
15762
  const { browser } = await launch({
15688
15763
  headless: true,
15689
15764
  args: ["--no-sandbox", "--disable-setuid-sandbox"]
@@ -15692,7 +15767,7 @@ var DataCollector = class {
15692
15767
  userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
15693
15768
  viewport: { width: 1920, height: 1080 }
15694
15769
  });
15695
- context._browser = browser;
15770
+ Reflect.set(context, "_browser", browser);
15696
15771
  return context;
15697
15772
  }
15698
15773
  sleep(ms) {
@@ -15723,7 +15798,7 @@ var DataCollector = class {
15723
15798
 
15724
15799
  // src/cdp-interceptor/index.ts
15725
15800
  async function createCDPInterceptor(config) {
15726
- const { CDPInterceptorProxy: CDPInterceptorProxy2 } = await import("./proxy-LV4BJ5RC.js");
15801
+ const { CDPInterceptorProxy: CDPInterceptorProxy2 } = await import("./proxy-C6CK3UH5.js");
15727
15802
  const proxy = new CDPInterceptorProxy2(config);
15728
15803
  await proxy.start();
15729
15804
  return proxy;
@@ -6,7 +6,8 @@ import {
6
6
  getCDPTargets,
7
7
  killChrome,
8
8
  launchChrome
9
- } from "./chunk-BBMRDUYQ.js";
9
+ } from "./chunk-TNEN6VQ2.js";
10
+ import "./chunk-GDKLH7ZY.js";
10
11
  import "./chunk-KFQGP6VL.js";
11
12
  export {
12
13
  ANTI_DETECT_ARGS,
@@ -6,7 +6,7 @@ import {
6
6
  getCDPTargets,
7
7
  killChrome,
8
8
  launchChrome
9
- } from "./chunk-JPHCY4TC.js";
9
+ } from "./chunk-AMI64BSD.js";
10
10
  import "./chunk-3RG5ZIWI.js";
11
11
  export {
12
12
  ANTI_DETECT_ARGS,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  CDPInterceptorProxy
3
- } from "./chunk-ZZ2TFWIV.js";
3
+ } from "./chunk-ABXMBNQ6.js";
4
4
  import "./chunk-KFQGP6VL.js";
5
5
  export {
6
6
  CDPInterceptorProxy
@@ -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-TOPYJIFL.js");
34
+ const { launch } = await import("./cdp-driver-D6WMSMWX.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.0.2",
3
+ "version": "1.0.3",
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": {