From 8c311fb049e888c8bf6c6ba82eb955c0f257c012 Mon Sep 17 00:00:00 2001 From: teernisse Date: Thu, 12 Feb 2026 16:14:01 -0500 Subject: [PATCH] Add comprehensive README with command reference and robot mode docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Covers: install, quick start, all 12 commands with full flag tables, robot mode activation (--robot, --json, env var, TTY auto-detect), JSON envelope schema, exit codes (0-16), configuration (auth profiles, aliases, network policy), and architecture overview (cache layout, index structure, SSRF protection model). Written for both human engineers and AI agents — structured enough for LLM consumption while remaining scannable for humans. --- README.md | 342 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f999b12 --- /dev/null +++ b/README.md @@ -0,0 +1,342 @@ +# swagger-cli + +A fast, cache-first CLI for exploring OpenAPI specifications. Built for engineering teams and AI agents. + +**Key properties:** +- Query latency: <50ms on cached specs (index-backed, no raw spec parsing) +- First query: <2s including fetch + index build +- Robot mode: 100% structured JSON output with versioned schema contract +- Exit codes: Consistent, actionable, concurrency-safe (14 error types, codes 2-16) +- Offline-capable: all queries work without network after initial fetch + +## Install + +```bash +cargo install --path . +``` + +Requires Rust 2024 edition. + +## Quick Start + +```bash +# Fetch and cache a spec +swagger-cli fetch https://petstore3.swagger.io/api/v3/openapi.json --alias petstore + +# List endpoints +swagger-cli list petstore + +# Search across the API +swagger-cli search petstore "pet" + +# Show endpoint details +swagger-cli show petstore "/pet/{petId}" --method GET + +# Browse schemas +swagger-cli schemas petstore + +# Machine-readable output (for agents) +swagger-cli list petstore --robot +``` + +## Commands + +### fetch + +Download and cache an OpenAPI spec. + +```bash +swagger-cli fetch --alias [OPTIONS] +``` + +`` accepts HTTP/HTTPS URLs, `file://` paths, relative paths, or `-` for stdin. + +| Option | Description | +|--------|-------------| +| `--alias ` | Required. Must match `^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$` | +| `-H, --header
` | Additional HTTP header (repeatable, format: `"Name: Value"`) | +| `--bearer ` | Bearer token for Authorization header | +| `--auth-profile ` | Auth profile name from config.toml | +| `--force` | Overwrite existing alias | +| `--timeout-ms ` | HTTP request timeout in milliseconds (default: 10000) | +| `--max-bytes ` | Maximum response size in bytes (default: 26214400 / ~25 MB) | +| `--retries ` | Retries on transient errors (default: 2) | +| `--allow-private-host ` | Bypass SSRF protection for this host (repeatable) | +| `--allow-insecure-http` | Permit plain HTTP | +| `--resolve-external-refs` | Fetch and inline external `$ref` entries | +| `--ref-allow-host ` | Allowed host for external ref fetching (repeatable, required with `--resolve-external-refs`) | +| `--ref-max-depth ` | Maximum chain depth for transitive external refs (default: 10) | +| `--ref-max-bytes ` | Maximum total bytes fetched for external refs (default: 10485760 / ~10 MB) | + +### list + +List endpoints from a cached spec. + +```bash +swagger-cli list [ALIAS] [OPTIONS] +``` + +| Option | Description | +|--------|-------------| +| `--all-aliases` | Query across every cached alias | +| `-m, --method ` | Filter by HTTP method (case-insensitive) | +| `-t, --tag ` | Filter by tag | +| `-p, --path ` | Filter by path pattern (regex) | +| `--sort ` | Sort order: path (default), method, or tag | +| `-n, --limit ` | Maximum results (default: 50) | +| `-a, --all` | Show all results (no limit) | + +### show + +Display details of a specific endpoint. + +```bash +swagger-cli show [OPTIONS] +``` + +| Option | Description | +|--------|-------------| +| `-m, --method ` | HTTP method to show. Required when path has multiple methods | +| `--expand-refs` | Expand `$ref` entries inline | +| `--max-depth ` | Maximum depth for ref expansion (default: 3) | + +Output includes the full operation object: summary, description, tags, operationId, security, parameters (path/query/header/cookie), request body, and response schemas with status codes. + +Circular references are detected and annotated with `{"$circular_ref": "..."}`. + +### search + +Full-text search across endpoints and schemas. + +```bash +swagger-cli search [ALIAS] [OPTIONS] +``` + +When using `--all-aliases`, the first positional argument is treated as the query. + +| Option | Description | +|--------|-------------| +| `--all-aliases` | Search across every cached alias | +| `--case-sensitive` | Case-sensitive matching | +| `--exact` | Match query as exact phrase | +| `--in ` | Fields to search (comma-separated): all (default), paths, descriptions, schemas | +| `--limit ` | Maximum results (default: 20) | + +Scoring is tokenized with field weights (path > summary > description) and term coverage boost, quantized to basis points for deterministic output. + +### schemas + +Browse component schemas. + +```bash +swagger-cli schemas [OPTIONS] +``` + +| Option | Description | +|--------|-------------| +| `--name ` | Filter schema names by regex | +| `--list` | List schemas (default mode) | +| `--show ` | Show a specific schema by exact name | +| `--expand-refs` | Expand `$ref` entries inline (show mode only) | +| `--max-depth ` | Maximum depth for ref expansion (default: 3) | + +### tags + +List tags from a cached spec with endpoint counts. + +```bash +swagger-cli tags +``` + +### aliases + +Manage spec aliases. + +```bash +swagger-cli aliases [OPTIONS] +``` + +| Option | Description | +|--------|-------------| +| `--list` | List all aliases (default) | +| `--show ` | Full details (URL, version, size, stats) | +| `--rename ` | Rename an alias | +| `--delete ` | Delete an alias and cached files | +| `--set-default ` | Set the default alias (used when ALIAS is omitted in other commands) | + +### sync + +Re-fetch and update cached specs. + +```bash +swagger-cli sync [ALIAS] [OPTIONS] +``` + +| Option | Description | +|--------|-------------| +| `--all` | Sync all cached specs | +| `--dry-run` | Check for changes without writing | +| `--force` | Re-fetch regardless of cache freshness | +| `--details` | Include per-item change lists in output (capped at 200 items) | +| `--auth ` | Auth profile name from config | +| `--jobs ` | Maximum concurrent sync jobs, `--all` only (default: 4) | +| `--per-host ` | Maximum concurrent requests per host, `--all` only (default: 2) | +| `--max-failures ` | Abort after N alias failures, `--all` only | +| `--resume` | Resume a previously interrupted `--all` sync | +| `--allow-private-host ` | Bypass SSRF protection for this host (repeatable) | + +Uses ETag + Last-Modified for conditional fetches. Respects `Retry-After` headers with exponential backoff. Per-alias progress checkpoints enable resumable execution. + +### diff + +Compare two spec versions (structural diff). + +```bash +swagger-cli diff [OPTIONS] +``` + +| Option | Description | +|--------|-------------| +| `--fail-on ` | Exit non-zero if changes at this level: `breaking` | +| `--details` | Include per-item change descriptions | + +Output covers added/removed/modified endpoints and schemas with a summary and breaking-change flag. Useful as a CI gate for API contract changes. + +### doctor + +Check cache health and diagnose issues. + +```bash +swagger-cli doctor [OPTIONS] +``` + +| Option | Description | +|--------|-------------| +| `--fix` | Attempt auto-repair | +| `--alias ` | Check a specific alias only | + +Checks: directory permissions, meta.json generation + index_hash validation, index pointer validity, stale caches (30+ days), index version compatibility, and torn/partial cache state. + +Fix modes: (1) rebuild index from raw, (2) reconstruct meta from raw + index, (3) delete alias only as last resort. + +### cache + +Manage the spec cache. + +```bash +swagger-cli cache [OPTIONS] +``` + +| Option | Description | +|--------|-------------| +| `--stats` | Show cache statistics (default) | +| `--path` | Print the cache directory path | +| `--prune-stale` | Remove aliases older than the stale threshold | +| `--prune-threshold ` | Days before an alias is stale (default: 90) | +| `--max-total-mb ` | LRU eviction until total size is under this limit | +| `--dry-run` | Preview without deleting | + +## Global Options + +Every command accepts these flags: + +| Flag | Description | +|------|-------------| +| `--robot` | Structured JSON output (auto-detects non-TTY) | +| `--pretty` | Pretty-print JSON output | +| `--network ` | `auto` (default), `online-only`, or `offline` | +| `--config ` | Path to config file (or `SWAGGER_CLI_CONFIG` env var) | + +## Robot Mode + +All commands support `--robot` for structured JSON output. Success: + +```json +{ + "ok": true, + "data": { ... }, + "meta": { + "schema_version": 1, + "tool_version": "0.1.0", + "command": "list", + "duration_ms": 12 + } +} +``` + +Errors emit JSON to stderr: + +```json +{ + "ok": false, + "error": { + "code": "ALIAS_NOT_FOUND", + "message": "Alias not found: myapi", + "suggestion": "Run 'swagger-cli aliases --list' to see available aliases." + }, + "meta": { ... } +} +``` + +## Exit Codes + +| Code | Error | Suggestion | +|------|-------|------------| +| 0 | Success | | +| 2 | `USAGE_ERROR` | Run `swagger-cli --help` | +| 4 | `NETWORK_ERROR` | Check connectivity or use `--network offline` | +| 5 | `INVALID_SPEC` | Verify URL points to valid OpenAPI 3.x JSON/YAML | +| 6 | `ALIAS_EXISTS` | Use `--force` to overwrite | +| 7 | `AUTH_ERROR` | Check auth profile in config.toml | +| 8 | `ALIAS_NOT_FOUND` | Run `aliases --list` to see available | +| 9 | `CACHE_LOCKED` | Wait or check for stale locks | +| 10 | `CACHE_ERROR` | Run `doctor --fix` | +| 11 | `CONFIG_ERROR` | Check config file, run `doctor` | +| 12 | `IO_ERROR` | File system error | +| 13 | `JSON_ERROR` | Invalid JSON/YAML parsing | +| 14 | `CACHE_INTEGRITY` | Run `doctor --fix` or re-fetch | +| 15 | `OFFLINE_MODE` | Use `--network auto` or `online-only` | +| 16 | `POLICY_BLOCKED` | Use `--allow-private-host` or `--allow-insecure-http` | + +## Configuration + +Config file location: `~/.config/swagger-cli/config.toml` (or set `SWAGGER_CLI_CONFIG`). + +```toml +[auth_profiles.corp_internal] +credential_source = "env:MY_API_TOKEN" +auth_type = "bearer" + +[auth_profiles.api_key] +credential_source = "env:API_KEY" +auth_type = "api_key" +header = "X-API-Key" +``` + +`credential_source` supports `env:VAR_NAME` and `file:/path/to/token`. + +## Cache Layout + +Specs are stored per-alias under `~/.cache/swagger-cli/aliases/{alias}/`: + +| File | Purpose | +|------|---------| +| `raw.source` | Original upstream bytes (YAML or JSON, lossless provenance) | +| `raw.json` | Canonical normalized JSON (all queries operate on this) | +| `index.json` | Precomputed query index (endpoints, schemas, tags, search data) | +| `meta.json` | Fetch metadata, written last as commit marker | + +The four-file protocol provides crash consistency: `meta.json` is written last with a generation counter and content hash, so a torn write is always detectable by `doctor`. + +## Security + +- **SSRF protection**: Blocks loopback, private ranges, and multicast addresses by default. Override per-host with `--allow-private-host`. +- **DNS rebinding mitigation**: Validates resolved IP after redirects (5 redirect limit). +- **Auth redaction**: Tokens are never printed in output or logs. +- **Streaming byte limit**: `--max-bytes` prevents OOM on oversized or malicious specs. +- **Network policy**: `--network offline` guarantees zero outbound connections. +- **External refs are opt-in**: `--resolve-external-refs` must be explicitly set with an allowlist of permitted hosts. + +## License + +MIT