From e1ac49e266dba835e8306f0a57a8e31a29c9356d Mon Sep 17 00:00:00 2001 From: Varun Nuthalapati Date: Thu, 28 May 2026 23:22:09 -0700 Subject: [PATCH 1/2] feat: add list-configs subcommand to CLI New users have no way to discover which config files are available without browsing the source tree. Add `python -m webwright.run.cli list-configs` that prints all .yaml filenames from the built-in config directory. Update the README flags table to document the new command. --- README.md | 5 +++-- src/webwright/run/cli.py | 13 ++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 891bbd7..0da4671 100644 --- a/README.md +++ b/README.md @@ -198,13 +198,14 @@ python -m webwright.run.cli \ ### 🚩 Flags -| Flag | Description | -|------|-------------| +| Flag / Command | Description | +|----------------|-------------| | `-c` | Config file(s) from `src/webwright/config/` (stackable). | | `-t` | Task instruction. | | `--start-url` | Initial page. | | `--task-id` | Output subfolder name. | | `-o` | Output directory. | +| `list-configs` | Print all available built-in config file names (`python -m webwright.run.cli list-configs`). | --- diff --git a/src/webwright/run/cli.py b/src/webwright/run/cli.py index 343ab70..061f589 100644 --- a/src/webwright/run/cli.py +++ b/src/webwright/run/cli.py @@ -8,7 +8,7 @@ from rich.console import Console from webwright.agents import get_agent -from webwright.config import get_config_from_spec, snapshot_config_specs +from webwright.config import builtin_config_dir, get_config_from_spec, snapshot_config_specs from webwright.environments import get_environment from webwright.models import get_model from webwright.utils.serialize import UNSET, recursive_merge @@ -134,6 +134,17 @@ def run_one( return result +@app.command("list-configs") +def list_configs() -> None: + """List all available built-in config files.""" + configs = sorted(builtin_config_dir.glob("*.yaml")) + if not configs: + console.print("No config files found.") + return + for path in configs: + console.print(path.name) + + @app.command() def main( task: str = typer.Option( From 89276cb2f943e567e321e21afeee689856d239ab Mon Sep 17 00:00:00 2001 From: Varun Nuthalapati Date: Tue, 2 Jun 2026 08:17:59 -0700 Subject: [PATCH 2/2] fix(cli): use callback pattern to avoid breaking no-subcommand invocation Registering a second @app.command() forced Typer to require an explicit subcommand, breaking the existing `python -m webwright.run.cli -t "..."` invocation form. Switch `main` to @app.callback(invoke_without_command=True) so the default invocation works without a subcommand while list-configs remains available as an explicit subcommand. Co-Authored-By: Claude Sonnet 4.6 --- src/webwright/run/cli.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/webwright/run/cli.py b/src/webwright/run/cli.py index 061f589..561c4c5 100644 --- a/src/webwright/run/cli.py +++ b/src/webwright/run/cli.py @@ -17,7 +17,7 @@ DEFAULT_CONFIGS = ["base.yaml", "model_openai.yaml"] -app = typer.Typer(no_args_is_help=True) +app = typer.Typer() console = Console(highlight=False) @@ -145,10 +145,11 @@ def list_configs() -> None: console.print(path.name) -@app.command() +@app.callback(invoke_without_command=True) def main( - task: str = typer.Option( - ..., "-t", "--task", help="Natural language task description." + ctx: typer.Context, + task: str | None = typer.Option( + None, "-t", "--task", help="Natural language task description." ), task_id: str | None = typer.Option( None, "--task-id", help="Optional identifier used in the output directory name." @@ -164,6 +165,11 @@ def main( help="Launch headed local Playwright with devtools and keep it open for inspection.", ), ) -> Any: + if ctx.invoked_subcommand is not None: + return + if task is None: + console.print(ctx.get_help()) + raise typer.Exit() return run_one( task=task, task_id=task_id,