cli: report usage errors once, accept -h, show tips only on a terminal

A flag given without its value, or an extra positional, failed with
only `FATAL exit err=MissingArgument`, not naming the flag. The parser
now logs which flag is missing its value or which argument is extra,
with a hint pointing at the command's help, and a missing fetch URL is
caught while parsing, next to run's missing script. Since each of these
is logged where it's found, main exits without the generic `exit` line.

`-h` works wherever `--help` does, instead of being taken as a URL.

The --obey-robots tip is for a person at a terminal, so it's skipped
when stderr isn't one; scripts capturing stderr no longer get it on
every run.
This commit is contained in:
Adrià Arrufat committed 2026-09-26 23:52:34 +02:00
1 parent 64b14b23e6
commit 1f582d4674
3 files changed
+47 -16

No files matched your search

+7 -2
View File
@@ -42,7 +42,7 @@ pub const CDP_TCP_USER_TIMEOUT_MS: c_int = 10_000;
const Config = @This();
fn logFilterValidator(allocator: Allocator, args: *std.process.Args.Iterator, list: *std.ArrayList(log.FilterRule)) !void {
const str = args.next() orelse return error.InvalidOption;
const str = args.next() orelse return error.MissingArgument;
defer log.opts.scope_enabled = log.resolveFilters(list.items);
@@ -730,7 +730,7 @@ var stderr_tty_once = lp.once(initStderrTty);
fn initStderrTty() void {
stderr_tty_cached = std.Io.File.stderr().isTty(lp.io) catch false;
}
fn stderrIsTty() bool {
pub fn stderrIsTty() bool {
stderr_tty_once.call();
return stderr_tty_cached;
}
@@ -1230,6 +1230,11 @@ pub fn parseArgs(allocator: Allocator, proc_args: std.process.Args) !Config {
command = .{ .agent = agent_opts };
}
if (command == .fetch and command.fetch.url.items.len == 0) {
log.fatal(.app, "missing URL", .{ .hint = "usage: lightpanda fetch <url>... [OPTIONS]" });
return error.MissingArgument;
}
// Agent mode quiets page-driven `console.error` noise unless
// verbosity=high. Depends on --verbosity/--task, so it can only be
// resolved after the options are parsed; an explicit --log-level wins.