"""`agnes describe ` — schema + sample rows (spec §4.1). Registered as a flat ``@app.command("describe")`` in ``cli/main.py`` rather than as a ``Typer.Typer`` subcommand-group + callback. The group pattern mis-parses ``agnes describe TABLE -n 5`` (positional + short option with a separated INTEGER value) — Typer hands the "5" to the positional and then errors on a missing TABLE_ID. There were no actual subcommands of ``describe`` to justify the group wrapping anyway. Issue surfaced from a real analyst session following the CLAUDE.md "agent rails" workflow. """ import json as json_lib import typer from cli.v2_client import api_get_json, V2ClientError def describe( table_id: str = typer.Argument(...), n: int = typer.Option(5, "-n", "--rows", help="Sample rows count"), json: bool = typer.Option(False, "--json"), ): """Show schema + sample rows for a table.""" try: sch = api_get_json(f"/api/v2/schema/{table_id}") sam = api_get_json(f"/api/v2/sample/{table_id}", n=n) except V2ClientError as e: typer.echo(f"Error: describe failed: {e}", err=True) raise typer.Exit(5 if e.status_code >= 500 else 8 if e.status_code == 403 else 2) if json: typer.echo(json_lib.dumps({"schema": sch, "sample": sam}, indent=2, default=str)) return typer.echo(f"Table: {sch['table_id']}") typer.echo("") typer.echo("Schema:") for c in sch.get("columns", []): typer.echo(f" {c['name']:30s} {c['type']}") typer.echo("") typer.echo(f"Sample ({len(sam.get('rows', []))} rows):") for row in sam.get("rows", []): typer.echo(f" {row}")