From 36cde1d488e1e2cf7085865401d4861723fed9d6 Mon Sep 17 00:00:00 2001 From: Valerio Date: Wed, 22 Jul 2026 17:47:23 +0200 Subject: [PATCH] fix(cli): also fix --diff/--brand for single-row --urls-file (review) Independent review found the backfill ran AFTER the --diff-with and --brand gates, so single-row --urls-file + --diff/--brand still hit 'no input'. Move the collect_urls + backfill before all mode gates so a one-line file behaves like a positional URL everywhere. --watch now reuses the shared entries instead of re-collecting (avoids double-counting the backfilled URL). Verified: --brand single-row no longer errors; 37 tests pass, clippy clean. Co-Authored-By: Claude Opus 4.8 (1M context) --- crates/webclaw-cli/src/main.rs | 36 ++++++++++++++-------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/crates/webclaw-cli/src/main.rs b/crates/webclaw-cli/src/main.rs index de98438..11da654 100644 --- a/crates/webclaw-cli/src/main.rs +++ b/crates/webclaw-cli/src/main.rs @@ -2779,6 +2779,20 @@ async fn main() { return; } + // Collect URLs from args + --urls-file up front, and backfill a lone + // --urls-file URL into cli.urls so a one-line file behaves like a positional + // URL across ALL modes below (crawl / watch / diff / brand / batch / single). + // See issue #86 — the mode gates and single path read cli.urls, which is + // empty when the URL came only from --urls-file. + let entries = match collect_urls(&cli) { + Ok(u) => u, + Err(e) => { + eprintln!("error: {e}"); + process::exit(1); + } + }; + backfill_single_file_url(&mut cli.urls, &entries); + // --crawl: recursive crawl mode if cli.crawl { if let Err(e) = run_crawl(&cli).await { @@ -2790,13 +2804,7 @@ async fn main() { // --watch: poll URL(s) for changes if cli.watch { - let watch_urls: Vec = match collect_urls(&cli) { - Ok(entries) => entries.into_iter().map(|(url, _)| url).collect(), - Err(e) => { - eprintln!("error: {e}"); - process::exit(1); - } - }; + let watch_urls: Vec = entries.iter().map(|(url, _)| url.clone()).collect(); if let Err(e) = run_watch(&cli, &watch_urls).await { eprintln!("error: {e}"); process::exit(1); @@ -2831,20 +2839,6 @@ async fn main() { return; } - // Collect all URLs from args + --urls-file - let entries = match collect_urls(&cli) { - Ok(u) => u, - Err(e) => { - eprintln!("error: {e}"); - process::exit(1); - } - }; - - // A single URL sourced only from --urls-file must behave like a positional - // URL (issue #86): the batch gates below require len > 1, and the single - // path reads cli.urls, so a one-line file would otherwise hit "no input". - backfill_single_file_url(&mut cli.urls, &entries); - // LLM modes: --extract-json, --extract-prompt, --summarize // When multiple URLs are provided, run batch LLM extraction over all of them. if has_llm_flags(&cli) {