Skip to content

feat: Migrate from Typer to cyclopts #18

Description

@ichoosetoaccept

Description

Migrate surfmon's CLI from Typer v0.24.1 to cyclopts v4.8.0, a modern competitor with:

  • Native support for Annotated types — single Parameter class instead of separate Argument/Option
  • Respects Python function signature semantics (positional/keyword) directly
  • Native Union/Optional support (Typer still lacks this)
  • Mutually exclusive options built-in
  • Has actual API docs (Typer still lacks them: #221)
  • No Click dependency — own internal parser, lighter stack
  • Auto-detects package version via importlib.metadata (built-in --version flag)
  • Rich help generation from docstrings
  • Pydantic, Dataclass, and Attrs support for complex types

Surfmon CLI Surface (8 commands)

Command Typer Features Used
check @app.command, typer.Option (6 opts), typer.Exit, TargetOption
watch @app.command, typer.Option (4 opts), typer.Exit, TargetOption
compare @app.command, typer.Argument (2 args), typer.Exit
cleanup @app.command, typer.Option, typer.confirm, typer.Exit
prune @app.command, typer.Argument, typer.Option, typer.confirm, typer.Exit
analyze @app.command, typer.Argument, typer.Option
pty-snapshot @app.command, typer.Option (4 opts), typer.Exit, TargetOption
ls-snapshot @app.command, typer.Option (4 opts), typer.Exit, TargetOption

Also uses: @app.callback() for --version/-V, typer.BadParameter, typer.echo, reusable TargetOption Annotated alias.

Migration Mapping (typer 0.24.1 → cyclopts 4.8.0)

Typer Cyclopts Notes
typer.Typer() cyclopts.App() Similar API
@app.callback() @app.default() / @app.meta.default() Version flag is built-in in cyclopts
@app.command() @app.command() Same
typer.Option(...) cyclopts.Parameter(...) Single class for both
typer.Argument(...) cyclopts.Parameter(...) Positional/keyword from signature
typer.Exit(code=N) raise SystemExit(N) No wrapper needed
typer.BadParameter(...) cyclopts.ValidationError(...) Or use validators
typer.confirm(...) cyclopts has no built-in — use rich.prompt.Confirm Already use Rich
typer.echo(...) print() or console.print() Already use Rich console

Tasks

  • Evaluate cyclopts API against current surfmon CLI surface
  • Migrate commands: check, watch, compare, cleanup, prune, analyze, pty-snapshot, ls-snapshot
  • Verify -h/--help, -V/--version shorthands
  • Migrate tests (uses typer.testing.CliRunner)
  • Update docs and README
  • Remove typer dependency

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions