@xbrowser/cli 1.4.8 → 1.5.1

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,7 +20,7 @@ import {
20
20
  saveSessionDiskMeta,
21
21
  setActivePage,
22
22
  touchSession
23
- } from "./chunk-M4U63K6B.js";
23
+ } from "./chunk-H7R352A2.js";
24
24
  import "./chunk-TNEN6VQ2.js";
25
25
  import "./chunk-GDKLH7ZY.js";
26
26
  import "./chunk-KFQGP6VL.js";
@@ -20,8 +20,8 @@ import {
20
20
  saveSessionDiskMeta,
21
21
  setActivePage,
22
22
  touchSession
23
- } from "./chunk-J7LDVYWI.js";
24
- import "./chunk-JGITVXIU.js";
23
+ } from "./chunk-WCM4FNUB.js";
24
+ import "./chunk-74QM55TC.js";
25
25
  import "./chunk-TNEN6VQ2.js";
26
26
  import "./chunk-GDKLH7ZY.js";
27
27
  import "./chunk-KFQGP6VL.js";
@@ -20,8 +20,8 @@ import {
20
20
  saveSessionDiskMeta,
21
21
  setActivePage,
22
22
  touchSession
23
- } from "./chunk-TP6RHIWG.js";
24
- import "./chunk-JGITVXIU.js";
23
+ } from "./chunk-MKEAO3XJ.js";
24
+ import "./chunk-74QM55TC.js";
25
25
  import "./chunk-TNEN6VQ2.js";
26
26
  import "./chunk-GDKLH7ZY.js";
27
27
  import "./chunk-ABXMBNQ6.js";
@@ -1177,17 +1177,43 @@ var XBPageImpl = class _XBPageImpl {
1177
1177
  headers: () => headers
1178
1178
  };
1179
1179
  }
1180
- async goBack(_opts = {}) {
1181
- const prevUrl = await this.evaluate("location.href").catch(() => "");
1180
+ async goBack(opts = {}) {
1181
+ try {
1182
+ const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
1183
+ if (navHistory.currentIndex > 0) {
1184
+ const prevUrl = navHistory.entries[navHistory.currentIndex - 1]?.url;
1185
+ if (prevUrl && prevUrl !== "about:blank") {
1186
+ await this.conn.send("Page.navigate", { url: prevUrl }, this.sessionId);
1187
+ await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
1188
+ });
1189
+ this._url = prevUrl;
1190
+ return;
1191
+ }
1192
+ }
1193
+ } catch {
1194
+ }
1182
1195
  await this.evaluate("() => history.back()");
1183
- await this.waitForTimeout(2e3);
1184
- this._url = await this.evaluate("location.href").catch(() => prevUrl);
1196
+ await this.waitForTimeout(3e3);
1197
+ this._url = await this.evaluate("location.href").catch(() => this._url);
1185
1198
  }
1186
- async goForward(_opts = {}) {
1187
- const prevUrl = await this.evaluate("location.href").catch(() => "");
1199
+ async goForward(opts = {}) {
1200
+ try {
1201
+ const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
1202
+ if (navHistory.currentIndex < navHistory.entries.length - 1) {
1203
+ const nextUrl = navHistory.entries[navHistory.currentIndex + 1]?.url;
1204
+ if (nextUrl && nextUrl !== "about:blank") {
1205
+ await this.conn.send("Page.navigate", { url: nextUrl }, this.sessionId);
1206
+ await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
1207
+ });
1208
+ this._url = nextUrl;
1209
+ return;
1210
+ }
1211
+ }
1212
+ } catch {
1213
+ }
1188
1214
  await this.evaluate("() => history.forward()");
1189
- await this.waitForTimeout(2e3);
1190
- this._url = await this.evaluate("location.href").catch(() => prevUrl);
1215
+ await this.waitForTimeout(3e3);
1216
+ this._url = await this.evaluate("location.href").catch(() => this._url);
1191
1217
  }
1192
1218
  async reload(opts = {}) {
1193
1219
  this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
@@ -14,7 +14,7 @@ import {
14
14
  scrollIntoView,
15
15
  waitForActionable,
16
16
  waitForNetworkIdle
17
- } from "./chunk-JGITVXIU.js";
17
+ } from "./chunk-74QM55TC.js";
18
18
  import {
19
19
  connectToCDP,
20
20
  findChrome,
@@ -1176,17 +1176,43 @@ var XBPageImpl = class _XBPageImpl {
1176
1176
  headers: () => headers
1177
1177
  };
1178
1178
  }
1179
- async goBack(_opts = {}) {
1180
- const prevUrl = await this.evaluate("location.href").catch(() => "");
1179
+ async goBack(opts = {}) {
1180
+ try {
1181
+ const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
1182
+ if (navHistory.currentIndex > 0) {
1183
+ const prevUrl = navHistory.entries[navHistory.currentIndex - 1]?.url;
1184
+ if (prevUrl && prevUrl !== "about:blank") {
1185
+ await this.conn.send("Page.navigate", { url: prevUrl }, this.sessionId);
1186
+ await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
1187
+ });
1188
+ this._url = prevUrl;
1189
+ return;
1190
+ }
1191
+ }
1192
+ } catch {
1193
+ }
1181
1194
  await this.evaluate("() => history.back()");
1182
- await this.waitForTimeout(2e3);
1183
- this._url = await this.evaluate("location.href").catch(() => prevUrl);
1195
+ await this.waitForTimeout(3e3);
1196
+ this._url = await this.evaluate("location.href").catch(() => this._url);
1184
1197
  }
1185
- async goForward(_opts = {}) {
1186
- const prevUrl = await this.evaluate("location.href").catch(() => "");
1198
+ async goForward(opts = {}) {
1199
+ try {
1200
+ const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
1201
+ if (navHistory.currentIndex < navHistory.entries.length - 1) {
1202
+ const nextUrl = navHistory.entries[navHistory.currentIndex + 1]?.url;
1203
+ if (nextUrl && nextUrl !== "about:blank") {
1204
+ await this.conn.send("Page.navigate", { url: nextUrl }, this.sessionId);
1205
+ await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
1206
+ });
1207
+ this._url = nextUrl;
1208
+ return;
1209
+ }
1210
+ }
1211
+ } catch {
1212
+ }
1187
1213
  await this.evaluate("() => history.forward()");
1188
- await this.waitForTimeout(2e3);
1189
- this._url = await this.evaluate("location.href").catch(() => prevUrl);
1214
+ await this.waitForTimeout(3e3);
1215
+ this._url = await this.evaluate("location.href").catch(() => this._url);
1190
1216
  }
1191
1217
  async reload(opts = {}) {
1192
1218
  this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
@@ -1182,17 +1182,43 @@ var XBPageImpl = class _XBPageImpl {
1182
1182
  headers: () => headers
1183
1183
  };
1184
1184
  }
1185
- async goBack(_opts = {}) {
1186
- const prevUrl = await this.evaluate("location.href").catch(() => "");
1185
+ async goBack(opts = {}) {
1186
+ try {
1187
+ const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
1188
+ if (navHistory.currentIndex > 0) {
1189
+ const prevUrl = navHistory.entries[navHistory.currentIndex - 1]?.url;
1190
+ if (prevUrl && prevUrl !== "about:blank") {
1191
+ await this.conn.send("Page.navigate", { url: prevUrl }, this.sessionId);
1192
+ await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
1193
+ });
1194
+ this._url = prevUrl;
1195
+ return;
1196
+ }
1197
+ }
1198
+ } catch {
1199
+ }
1187
1200
  await this.evaluate("() => history.back()");
1188
- await this.waitForTimeout(2e3);
1189
- this._url = await this.evaluate("location.href").catch(() => prevUrl);
1201
+ await this.waitForTimeout(3e3);
1202
+ this._url = await this.evaluate("location.href").catch(() => this._url);
1190
1203
  }
1191
- async goForward(_opts = {}) {
1192
- const prevUrl = await this.evaluate("location.href").catch(() => "");
1204
+ async goForward(opts = {}) {
1205
+ try {
1206
+ const navHistory = await this.conn.send("Page.getNavigationHistory", void 0, this.sessionId);
1207
+ if (navHistory.currentIndex < navHistory.entries.length - 1) {
1208
+ const nextUrl = navHistory.entries[navHistory.currentIndex + 1]?.url;
1209
+ if (nextUrl && nextUrl !== "about:blank") {
1210
+ await this.conn.send("Page.navigate", { url: nextUrl }, this.sessionId);
1211
+ await this.waitForLoadState(opts.waitUntil ?? "domcontentloaded", opts.timeout ?? 1e4).catch(() => {
1212
+ });
1213
+ this._url = nextUrl;
1214
+ return;
1215
+ }
1216
+ }
1217
+ } catch {
1218
+ }
1193
1219
  await this.evaluate("() => history.forward()");
1194
- await this.waitForTimeout(2e3);
1195
- this._url = await this.evaluate("location.href").catch(() => prevUrl);
1220
+ await this.waitForTimeout(3e3);
1221
+ this._url = await this.evaluate("location.href").catch(() => this._url);
1196
1222
  }
1197
1223
  async reload(opts = {}) {
1198
1224
  this._loadState = { loadFired: false, domContentFired: false, networkIdle: false };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  launch
3
- } from "./chunk-JGITVXIU.js";
3
+ } from "./chunk-74QM55TC.js";
4
4
  import {
5
5
  errMsg
6
6
  } from "./chunk-GDKLH7ZY.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  launch
3
- } from "./chunk-JGITVXIU.js";
3
+ } from "./chunk-74QM55TC.js";
4
4
  import {
5
5
  errMsg
6
6
  } from "./chunk-GDKLH7ZY.js";
package/dist/cli.js CHANGED
@@ -25,7 +25,7 @@ import {
25
25
  resolveLaunchOpts,
26
26
  saveSessionDiskMeta,
27
27
  setActivePage
28
- } from "./chunk-M4U63K6B.js";
28
+ } from "./chunk-H7R352A2.js";
29
29
  import "./chunk-TNEN6VQ2.js";
30
30
  import {
31
31
  forwardCommandLog,
@@ -5221,6 +5221,9 @@ var tabCommand = registerCommand({
5221
5221
  data: z23.unknown()
5222
5222
  }),
5223
5223
  handler: async (p, ctx) => {
5224
+ if (!ctx.browserContext) {
5225
+ return fail6("No browser context available. Use --cdp to connect to a browser first.");
5226
+ }
5224
5227
  const pages = ctx.browserContext.pages();
5225
5228
  switch (p.subcommand) {
5226
5229
  case "list":
@@ -7083,7 +7086,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7083
7086
  }
7084
7087
  let targetPageOverride = null;
7085
7088
  if (_target && extraOpts?.cdpEndpoint) {
7086
- const { findTargetPage } = await import("./browser-4KKT6V5S.js");
7089
+ const { findTargetPage } = await import("./browser-2FJ4OO4H.js");
7087
7090
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
7088
7091
  if (!targetPageOverride) {
7089
7092
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -11744,8 +11747,13 @@ Commands:
11744
11747
  session close [--session <name>] Close session
11745
11748
  session list List sessions
11746
11749
  session kill [--session <name>] Kill session
11750
+
11747
11751
  goto <url> Navigate to URL
11748
11752
  open <url> Navigate to URL (alias for goto)
11753
+ back Go back in history
11754
+ forward Go forward in history
11755
+ refresh Reload page
11756
+
11749
11757
  click <selector> Click element (-s <sel>)
11750
11758
  fill <selector> <value> Fill input (-s <sel> -v <val>)
11751
11759
  type <selector> <text> Type text (-s <sel> -v <text>)
@@ -11755,21 +11763,61 @@ Commands:
11755
11763
  dblclick <selector> Double click (-s <sel>)
11756
11764
  check <selector> Check checkbox (-s <sel>)
11757
11765
  uncheck <selector> Uncheck checkbox (-s <sel>)
11758
- screenshot [--full-page] [--base64] Take screenshot (saves to ~/.xbrowser/screenshots/; use --base64 for inline data)
11766
+ mouse <action> <x> <y> Mouse move/click at coordinates
11767
+ scroll <direction> [--distance N] Scroll page
11768
+
11769
+ screenshot [--full-page] [--base64] Take screenshot
11759
11770
  eval <expression> Evaluate JS
11760
11771
  wait <selector> [--timeout <ms>] Wait for element (-s <sel>)
11761
- scroll <direction> [--distance N] Scroll page
11772
+ waitForTimeout <ms> Wait for milliseconds
11773
+ waitFor --text <t> Wait for text/url/selector predicate
11762
11774
  title Get page title
11763
11775
  url Get current URL
11764
11776
  html [--selector <sel>] Get HTML content
11765
11777
  text [--selector <sel>] Get text content
11778
+ find <strategy> <value> [--action click|fill|hover] Find element by text/role/label
11779
+
11780
+ set-viewport <width> <height> Set viewport size
11781
+ frames List all frames
11782
+ frame --index <n> Switch to frame
11783
+ tab list List browser tabs
11784
+ tab new <url> Open new tab
11785
+ tab close --index <n> Close tab
11786
+ tab switch --index <n> Switch to tab
11787
+
11788
+ get-cookies Get all cookies
11789
+ set-cookie <name> <value> Set cookie
11790
+ clear-cookies Clear cookies
11791
+ get-local-storage Get localStorage
11792
+ set-local-storage <key> <value> Set localStorage item
11793
+ clear-local-storage Clear localStorage
11794
+
11795
+ snapshot Get page snapshot with element refs
11796
+ observe AI agent: observe page state
11797
+ act AI agent: perform action
11798
+ actions <url> --action "..." Execute action sequence
11799
+
11800
+ console Get console messages
11801
+ net-debug Get network debug info
11802
+ perf Get performance metrics
11803
+ health Run page health check (SEO/links/errors)
11804
+ structure Get page DOM structure
11805
+ network <url> Capture network traffic
11806
+ addinitscript <script> Add init script
11807
+
11808
+ scrape <url> Scrape page to markdown
11809
+ crawl <url> Crawl website (multi-page)
11810
+ search "query" Search the web (--engine, --limit, --full)
11811
+ map <url> Discover all URLs on a website
11812
+
11766
11813
  convert <rec.yaml> <out.{js,py,sh}> Convert recording to script
11767
11814
  extract <rec.yaml> Extract LLM-ready summary
11768
11815
  filter <in.yaml> <out.yaml> Filter recording events
11769
- scrape <url> Scrape a page and convert to markdown
11770
- crawl <url> Crawl a website and extract content from multiple pages
11771
- search "query" Search the web and extract results (--engine, --limit, --full)
11772
- map <url> Discover all URLs on a website
11816
+ replay <file> Replay recording
11817
+ record start --url <url> Start recording
11818
+ record stop Stop recording
11819
+ record status Recording status
11820
+
11773
11821
  config <get|set|list> Manage config
11774
11822
  plugin search <query> Search for plugins
11775
11823
  plugin install <source> Install plugin
@@ -11777,16 +11825,12 @@ Commands:
11777
11825
  plugin list List plugins
11778
11826
  plugin reload <name> Reload plugin
11779
11827
  create <name> --template <type> Create plugin
11780
- serve [--port <port>] [--token <t>] Start HTTP server for remote access
11781
- remote <url> [command] [--token <t>] Execute command on remote server
11782
- record start --url <url> Start recording
11783
- record stop Stop recording
11784
- record status Recording status
11785
- replay <file> Replay recording
11828
+ serve [--port <port>] [--token <t>] Start HTTP server
11829
+ remote <url> [command] [--token <t>] Execute on remote server
11786
11830
  run <file> Execute commands from file
11787
- viewer [--name <n>] [--selector <sel>] Generate viewer URL
11831
+ viewer [--name <n>] Generate viewer URL
11788
11832
  help Show this help
11789
- --version, -v Show version
11833
+ --version Show version
11790
11834
  Plugin Commands:
11791
11835
  Installed plugins provide additional commands.
11792
11836
  Use 'xbrowser plugin list' to see installed plugins and their commands.
@@ -11832,7 +11876,7 @@ Global Flags:
11832
11876
  --session <name> Use specific session
11833
11877
  --cdp <endpoint> Connect via CDP (url, port, or 'auto')
11834
11878
  --help, -h Show help
11835
- `);
11879
+ `);
11836
11880
  }
11837
11881
 
11838
11882
  // src/cli/chain-output.ts
@@ -13059,7 +13103,7 @@ async function main() {
13059
13103
  const command = process.argv[2];
13060
13104
  const isLongRunning = command === "preview" || command === "serve";
13061
13105
  if (!isLongRunning) {
13062
- const { ensureProcessCanExit } = await import("./browser-4KKT6V5S.js");
13106
+ const { ensureProcessCanExit } = await import("./browser-2FJ4OO4H.js");
13063
13107
  await ensureProcessCanExit().catch(() => {
13064
13108
  });
13065
13109
  process.exit(exitCode);
@@ -21,8 +21,8 @@ import {
21
21
  resolveLaunchOpts,
22
22
  saveSessionDiskMeta,
23
23
  setActivePage
24
- } from "./chunk-J7LDVYWI.js";
25
- import "./chunk-JGITVXIU.js";
24
+ } from "./chunk-WCM4FNUB.js";
25
+ import "./chunk-74QM55TC.js";
26
26
  import "./chunk-TNEN6VQ2.js";
27
27
  import {
28
28
  getPluginLoader
@@ -5182,6 +5182,9 @@ var tabCommand = registerCommand({
5182
5182
  data: z23.unknown()
5183
5183
  }),
5184
5184
  handler: async (p, ctx) => {
5185
+ if (!ctx.browserContext) {
5186
+ return fail6("No browser context available. Use --cdp to connect to a browser first.");
5187
+ }
5185
5188
  const pages = ctx.browserContext.pages();
5186
5189
  switch (p.subcommand) {
5187
5190
  case "list":
@@ -6614,7 +6617,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
6614
6617
  }
6615
6618
  let targetPageOverride = null;
6616
6619
  if (_target && extraOpts?.cdpEndpoint) {
6617
- const { findTargetPage } = await import("./browser-MMIFKC36.js");
6620
+ const { findTargetPage } = await import("./browser-IS6DTR5Y.js");
6618
6621
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
6619
6622
  if (!targetPageOverride) {
6620
6623
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -8330,7 +8333,7 @@ function createRPCHandler() {
8330
8333
  const isNewFormat = Array.isArray(parsed.actions);
8331
8334
  if (isNewFormat) {
8332
8335
  try {
8333
- const { SessionReplayer } = await import("./session-replayer-JIH6H7WX.js");
8336
+ const { SessionReplayer } = await import("./session-replayer-SD2MWGP5.js");
8334
8337
  const replayer = new SessionReplayer({
8335
8338
  page: session.page,
8336
8339
  stepDelay: slowMo * 500,
package/dist/index.js CHANGED
@@ -81,8 +81,8 @@ import {
81
81
  resolveLaunchOpts,
82
82
  saveSessionDiskMeta,
83
83
  setActivePage
84
- } from "./chunk-TP6RHIWG.js";
85
- import "./chunk-JGITVXIU.js";
84
+ } from "./chunk-MKEAO3XJ.js";
85
+ import "./chunk-74QM55TC.js";
86
86
  import "./chunk-TNEN6VQ2.js";
87
87
  import {
88
88
  errMsg
@@ -5538,6 +5538,9 @@ var tabCommand = registerCommand({
5538
5538
  data: z23.unknown()
5539
5539
  }),
5540
5540
  handler: async (p, ctx) => {
5541
+ if (!ctx.browserContext) {
5542
+ return fail6("No browser context available. Use --cdp to connect to a browser first.");
5543
+ }
5541
5544
  const pages = ctx.browserContext.pages();
5542
5545
  switch (p.subcommand) {
5543
5546
  case "list":
@@ -7403,7 +7406,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7403
7406
  }
7404
7407
  let targetPageOverride = null;
7405
7408
  if (_target && extraOpts?.cdpEndpoint) {
7406
- const { findTargetPage } = await import("./browser-FKKMMB44.js");
7409
+ const { findTargetPage } = await import("./browser-ZFW2XADE.js");
7407
7410
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
7408
7411
  if (!targetPageOverride) {
7409
7412
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -12084,8 +12087,13 @@ Commands:
12084
12087
  session close [--session <name>] Close session
12085
12088
  session list List sessions
12086
12089
  session kill [--session <name>] Kill session
12090
+
12087
12091
  goto <url> Navigate to URL
12088
12092
  open <url> Navigate to URL (alias for goto)
12093
+ back Go back in history
12094
+ forward Go forward in history
12095
+ refresh Reload page
12096
+
12089
12097
  click <selector> Click element (-s <sel>)
12090
12098
  fill <selector> <value> Fill input (-s <sel> -v <val>)
12091
12099
  type <selector> <text> Type text (-s <sel> -v <text>)
@@ -12095,21 +12103,61 @@ Commands:
12095
12103
  dblclick <selector> Double click (-s <sel>)
12096
12104
  check <selector> Check checkbox (-s <sel>)
12097
12105
  uncheck <selector> Uncheck checkbox (-s <sel>)
12098
- screenshot [--full-page] [--base64] Take screenshot (saves to ~/.xbrowser/screenshots/; use --base64 for inline data)
12106
+ mouse <action> <x> <y> Mouse move/click at coordinates
12107
+ scroll <direction> [--distance N] Scroll page
12108
+
12109
+ screenshot [--full-page] [--base64] Take screenshot
12099
12110
  eval <expression> Evaluate JS
12100
12111
  wait <selector> [--timeout <ms>] Wait for element (-s <sel>)
12101
- scroll <direction> [--distance N] Scroll page
12112
+ waitForTimeout <ms> Wait for milliseconds
12113
+ waitFor --text <t> Wait for text/url/selector predicate
12102
12114
  title Get page title
12103
12115
  url Get current URL
12104
12116
  html [--selector <sel>] Get HTML content
12105
12117
  text [--selector <sel>] Get text content
12118
+ find <strategy> <value> [--action click|fill|hover] Find element by text/role/label
12119
+
12120
+ set-viewport <width> <height> Set viewport size
12121
+ frames List all frames
12122
+ frame --index <n> Switch to frame
12123
+ tab list List browser tabs
12124
+ tab new <url> Open new tab
12125
+ tab close --index <n> Close tab
12126
+ tab switch --index <n> Switch to tab
12127
+
12128
+ get-cookies Get all cookies
12129
+ set-cookie <name> <value> Set cookie
12130
+ clear-cookies Clear cookies
12131
+ get-local-storage Get localStorage
12132
+ set-local-storage <key> <value> Set localStorage item
12133
+ clear-local-storage Clear localStorage
12134
+
12135
+ snapshot Get page snapshot with element refs
12136
+ observe AI agent: observe page state
12137
+ act AI agent: perform action
12138
+ actions <url> --action "..." Execute action sequence
12139
+
12140
+ console Get console messages
12141
+ net-debug Get network debug info
12142
+ perf Get performance metrics
12143
+ health Run page health check (SEO/links/errors)
12144
+ structure Get page DOM structure
12145
+ network <url> Capture network traffic
12146
+ addinitscript <script> Add init script
12147
+
12148
+ scrape <url> Scrape page to markdown
12149
+ crawl <url> Crawl website (multi-page)
12150
+ search "query" Search the web (--engine, --limit, --full)
12151
+ map <url> Discover all URLs on a website
12152
+
12106
12153
  convert <rec.yaml> <out.{js,py,sh}> Convert recording to script
12107
12154
  extract <rec.yaml> Extract LLM-ready summary
12108
12155
  filter <in.yaml> <out.yaml> Filter recording events
12109
- scrape <url> Scrape a page and convert to markdown
12110
- crawl <url> Crawl a website and extract content from multiple pages
12111
- search "query" Search the web and extract results (--engine, --limit, --full)
12112
- map <url> Discover all URLs on a website
12156
+ replay <file> Replay recording
12157
+ record start --url <url> Start recording
12158
+ record stop Stop recording
12159
+ record status Recording status
12160
+
12113
12161
  config <get|set|list> Manage config
12114
12162
  plugin search <query> Search for plugins
12115
12163
  plugin install <source> Install plugin
@@ -12117,16 +12165,12 @@ Commands:
12117
12165
  plugin list List plugins
12118
12166
  plugin reload <name> Reload plugin
12119
12167
  create <name> --template <type> Create plugin
12120
- serve [--port <port>] [--token <t>] Start HTTP server for remote access
12121
- remote <url> [command] [--token <t>] Execute command on remote server
12122
- record start --url <url> Start recording
12123
- record stop Stop recording
12124
- record status Recording status
12125
- replay <file> Replay recording
12168
+ serve [--port <port>] [--token <t>] Start HTTP server
12169
+ remote <url> [command] [--token <t>] Execute on remote server
12126
12170
  run <file> Execute commands from file
12127
- viewer [--name <n>] [--selector <sel>] Generate viewer URL
12171
+ viewer [--name <n>] Generate viewer URL
12128
12172
  help Show this help
12129
- --version, -v Show version
12173
+ --version Show version
12130
12174
  Plugin Commands:
12131
12175
  Installed plugins provide additional commands.
12132
12176
  Use 'xbrowser plugin list' to see installed plugins and their commands.
@@ -12172,7 +12216,7 @@ Global Flags:
12172
12216
  --session <name> Use specific session
12173
12217
  --cdp <endpoint> Connect via CDP (url, port, or 'auto')
12174
12218
  --help, -h Show help
12175
- `);
12219
+ `);
12176
12220
  }
12177
12221
 
12178
12222
  // src/cli/chain-output.ts
@@ -16186,7 +16230,7 @@ var DataCollector = class {
16186
16230
  return results;
16187
16231
  }
16188
16232
  async createBrowserContext() {
16189
- const { launch } = await import("./cdp-driver-OY67R2KD.js");
16233
+ const { launch } = await import("./cdp-driver-QHTXQRQ2.js");
16190
16234
  const { browser } = await launch({
16191
16235
  headless: true,
16192
16236
  args: ["--no-sandbox", "--disable-setuid-sandbox"]
@@ -31,7 +31,7 @@ var SessionReplayer = class {
31
31
  if (this.opts.page) {
32
32
  this.page = this.opts.page;
33
33
  } else if (this.opts.cdpUrl) {
34
- const { launch } = await import("./cdp-driver-OY67R2KD.js");
34
+ const { launch } = await import("./cdp-driver-QHTXQRQ2.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.4.8",
3
+ "version": "1.5.1",
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": {