@zenrows/cli 1.6.1 → 1.6.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.
package/README.md CHANGED
@@ -187,7 +187,10 @@ to open. `--max-items` and `--max-pages` cap the crawl (API default 100 each),
187
187
  and `--max-pages` bounds the cost, since each page is one fetch. The local policy `max_pages_per_run` caps `--max-pages` (default
188
188
  1000). `--output-format html` uses up the page budget: each kept page is one
189
189
  more fetch, and `--max-pages` counts it. `--include-patterns` /
190
- `--exclude-patterns` are repeatable substring filters on the URL. `get` and
190
+ `--exclude-patterns` are repeatable substring filters on the URL. A crawl whose
191
+ pages held nothing new to follow ends `completed` with no results and exits 0.
192
+ When patterns were set, it prints a note (under `--json`, in `note`) to check
193
+ them against the URLs the start page links to. `get` and
191
194
  `list` read one page and take `--cursor` and `--limit`. `results` follows every
192
195
  page (`--limit` is the page size); on a running crawl it returns the URLs kept
193
196
  so far, with `partial: true`. `download` reports the crawl's `status` (`null`
@@ -62,7 +62,8 @@ export const crawl = {
62
62
  " a crawl still running then is printed, not stopped",
63
63
  " --json print structured output: create/get/wait/stop print",
64
64
  " {ok, crawl_id, status, crawl}; get adds results and next_cursor;",
65
- " a wait that runs out adds note",
65
+ " a wait that runs out, or a completed crawl with patterns",
66
+ " and 0 results, adds note",
66
67
  ].join("\n"),
67
68
  async run(argv, ctx) {
68
69
  const [sub, ...rest] = argv;
@@ -466,8 +467,8 @@ export function crawlFailure(c) {
466
467
  }
467
468
  const why = [code, c.error?.detail].filter(Boolean).join(": ");
468
469
  const next = {
469
- seed_unreachable: "The start URL could not be fetched (the site may be blocking it). Check it with `zenrows fetch <url>`.",
470
- no_items_found: "Nothing matched. Loosen --include-patterns / --exclude-patterns, raise or drop --depth, or check the start page with `zenrows fetch <url>`.",
470
+ seed_unreachable: "The start URL could not be fetched or returned an empty page (the site may be blocking it). Check it with `zenrows fetch <url>`.",
471
+ no_items_found: "The crawl read the start page but found no data it could use, so it had nothing to follow. Start from a listing or product page.",
471
472
  };
472
473
  return new ToolkitError({
473
474
  code: "CRAWL_FAILED",
@@ -478,6 +479,18 @@ export function crawlFailure(c) {
478
479
  ...ids,
479
480
  });
480
481
  }
482
+ /**
483
+ * Set only when a crawl with patterns completed and kept nothing. The API ends a
484
+ * crawl whose pages held nothing new to follow `completed`, and does not count
485
+ * the links the patterns rejected, so the patterns are the first thing to check.
486
+ */
487
+ function noMatchNote(c) {
488
+ const crawl = c;
489
+ const patterns = [...(crawl.include_patterns ?? []), ...(crawl.exclude_patterns ?? [])];
490
+ if (crawl.status !== "completed" || crawl.coverage?.items_found !== 0 || !patterns.length)
491
+ return undefined;
492
+ return "The crawl completed with no results. Check --include-patterns / --exclude-patterns against the URLs the start page links to.";
493
+ }
481
494
  /**
482
495
  * Print a crawl (or a stop answer), structured under --json, and return the exit
483
496
  * code: 1 when it ended `failed`, or `stopped` because credits ran out or the
@@ -487,6 +500,7 @@ export function crawlFailure(c) {
487
500
  */
488
501
  function printCrawl(c, json, headline, extra = {}) {
489
502
  const err = crawlFailure(c);
503
+ const note = extra.note ?? noMatchNote(c);
490
504
  const crawlFields = { ...c };
491
505
  // A wait polls with one result to stay cheap; that page is not "the results".
492
506
  delete crawlFields.results;
@@ -498,6 +512,7 @@ function printCrawl(c, json, headline, extra = {}) {
498
512
  status: c.status,
499
513
  crawl: crawlFields,
500
514
  ...extra,
515
+ note,
501
516
  ...(err ? { error: err.toJSON() } : {}),
502
517
  }, null, 2));
503
518
  return err ? 1 : 0;
@@ -515,6 +530,8 @@ function printCrawl(c, json, headline, extra = {}) {
515
530
  }
516
531
  if (extra.note)
517
532
  log.dim(` next: zenrows crawl wait ${c.crawl_id}`);
533
+ else if (note)
534
+ log.warn(` ${note}`);
518
535
  if (err)
519
536
  printError(err, false);
520
537
  return err ? 1 : 0;
@@ -14,7 +14,7 @@ export const CONFIG_VERSION = "0.1.0";
14
14
  * entrypoint) so core modules — telemetry, signup provenance — can read it
15
15
  * without an import cycle. `VERSION` in `cli/index.ts` re-exports this.
16
16
  */
17
- export const CLI_VERSION = "1.6.1"; // x-release-please-version
17
+ export const CLI_VERSION = "1.6.2"; // x-release-please-version
18
18
  /** The User-Agent on every request to a Zenrows API. The gateway reads the version from it. */
19
19
  export const CLI_USER_AGENT = `zenrows-cli/${CLI_VERSION}`;
20
20
  /** Env var to override the Fetch and Extract API base (local/staging testing). */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenrows/cli",
3
- "version": "1.6.1",
3
+ "version": "1.6.2",
4
4
  "description": "Open-source CLI, MCP, skills, templates, workflows, recipes, and evals layer for giving AI agents reliable access to protected web data through Zenrows cloud infrastructure.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -39,6 +39,10 @@ zenrows crawl results <id> --out urls.jsonl # same, as JSONL
39
39
  - `--include-patterns` / `--exclude-patterns` are substring matches on the
40
40
  normalized URL and repeat:
41
41
  `--include-patterns /product/ --exclude-patterns ?add-to-cart`.
42
+ - A crawl whose pages held nothing new to follow (no link, only links to other
43
+ sites, or only links the patterns reject) ends `completed` with no results
44
+ and exits 0. When patterns were set, it prints a note (under `--json`, in
45
+ `note`) to check them against the URLs the start page links to.
42
46
  - `create` returns at once. `--follow` (or `zenrows crawl wait <id>`) polls
43
47
  until the crawl ends or `--timeout` seconds run out (default 600). When the
44
48
  time runs out, the command exits 0 and prints the crawl with status
@@ -85,7 +89,10 @@ credit cap; the pages fetched before that stay readable. `failed`, and a
85
89
  `stopped` crawl with an `error`, exit non-zero: `CRAWL_INSUFFICIENT_CREDITS` or
86
90
  `CRAWL_KEY_CAP_REACHED` when credits ended it (the same codes a refused
87
91
  `create` gets, also when an older deployment reports it `failed`), else
88
- `CRAWL_FAILED`. `server_code` carries the API's `error.code`.
92
+ `CRAWL_FAILED`. `server_code` carries the API's `error.code`:
93
+ `seed_unreachable` when the start URL could not be fetched or returned an empty
94
+ page, `no_items_found` when the crawl read the start page but found no data it
95
+ could use.
89
96
  `stop` on a crawl that already ended prints the status it ended with.
90
97
 
91
98
  With `--json`, `create`, `get`, `wait` and `stop` print