Derive a noun-verb command tree from an OpenAPI document
Turn operationIds, tags and paths into a committed map of noun, verb and operationId that any CLI framework can implement, with collisions resolved in the map.
How-to › Section 7
Command-line and interactive surfaces over an API, for humans, scripts and agents: building, making usable, distributing, and exploring an API before writing code.
7 guides in 4 topics. Every guide compares its approaches and shows the output its commands printed.
Generating or hand-writing a CLI: restish over any OpenAPI document, the go-cli target generated from a semantic model, oclif and commander, cobra, click and typer, clap, Thor, Symfony Console, and a gh-style resource-shaped command tree; mapping operationIds to commands, flags and auth, and curl plus jq or HTTPie as the do-nothing baseline.
Turn operationIds, tags and paths into a committed map of noun, verb and operationId that any CLI framework can implement, with collisions resolved in the map.
Extend the command map with a parameter map: path parameters as positional arguments, query and header parameters as flags, and one input style for request bodies.
Output formats (table, JSON, YAML, --jq), stable exit codes, TTY detection and color, paging, progress, shell completion, help text, config files and profiles, environment variable precedence, keychain token storage after a device-flow login, and designing a CLI that a coding agent can drive.
Give a CLI machine-readable output, exit codes that mean one thing each, and a confirmation rule that never depends on a terminal being attached.
Describe the command surface once, render it as text and as data, and lint the result so a command cannot ship with an example that does not run.
Golden-file and snapshot tests across operating systems, end-to-end tests against a mock API, then distribution with goreleaser, Homebrew taps, Scoop, npm, pipx, Docker images, code signing and notarization, and update checks.
Test a confirmation prompt without a real terminal, by passing the streams and the terminal flag in rather than reading them from the process.
Trying calls before writing code: language REPLs with an SDK loaded and tab completion from the model, generated REPL surfaces (the sdkgen REPL as in the existing blog post, seneca-repl), prompt_toolkit and IPython shells, Postman, Bruno, Insomnia and Hoppscotch collections generated from OpenAPI and kept in git, GraphiQL, Swagger UI try-it, HTTPie sessions, and a keyboard-first command bar over an API's operations (cmdk, kbar, voxgig-ui as options).
Start a REPL with the client already built and its entities named, so exploring an API is one command rather than six lines of setup typed from memory.
Convert a REPL history into a script that runs, by dropping the lines that threw, the expressions typed to look at a value, and the REPL's own commands.
Retries, timeouts, pagination and auth are the same problems in every client. Voxgig generates them from your OpenAPI description, in 23 languages, from one model.