|
| 1 | +# wherobots-cli |
| 2 | + |
| 3 | +Guidance for AI coding agents (Claude Code, Copilot, Codex) working in this repository. |
| 4 | + |
| 5 | +## What This Is |
| 6 | + |
| 7 | +`wherobots` CLI — a Go command-line tool for the Wherobots Cloud API. It has two command groups: |
| 8 | +- **`job-runs`** — curated commands for submitting Spark jobs, streaming logs, listing runs, and viewing metrics |
| 9 | +- **Dynamic API commands** — generated at runtime from the Wherobots OpenAPI spec, so every API endpoint is available as a CLI command |
| 10 | + |
| 11 | +## Build & Development Commands |
| 12 | + |
| 13 | +```bash |
| 14 | +make build # compile to bin/wherobots |
| 15 | +make test # go test ./... |
| 16 | +make fmt # go fmt ./... |
| 17 | +make tidy # go mod tidy |
| 18 | +make run ARGS='...' # run without building (e.g., make run ARGS='job-runs list') |
| 19 | +make clean # remove bin/ |
| 20 | +``` |
| 21 | + |
| 22 | +Run a single test: |
| 23 | +```bash |
| 24 | +go test -run TestName ./internal/commands/ |
| 25 | +``` |
| 26 | + |
| 27 | +Runtime credentials: `wherobots auth login` (OAuth device flow, stored session) or the `WHEROBOTS_API_KEY` env var. The env var takes precedence when both are present. |
| 28 | + |
| 29 | +## Architecture |
| 30 | + |
| 31 | +### Dynamic Command Generation |
| 32 | + |
| 33 | +The CLI builds its command tree at startup from a live OpenAPI spec. `internal/spec/loader.go` fetches and caches the spec (`~/.cache/wherobots/spec.json`, 15min TTL), `internal/spec/parser.go` extracts operations, and `internal/commands/builder.go` converts each operation into a Cobra command with flags for path params, query params, and request body fields. |
| 34 | + |
| 35 | +### Curated `job-runs` Commands |
| 36 | + |
| 37 | +`internal/commands/jobs.go` defines hand-written commands (`create`, `logs`, `list`, `running`, `failed`, `completed`, `metrics`) that layer workflow logic on top of the API: auto-uploading local scripts to S3 via presigned URLs, log streaming with polling, status watching, and formatted output. |
| 38 | + |
| 39 | +### Request Execution Pipeline |
| 40 | + |
| 41 | +`internal/executor/request.go` builds authenticated HTTP requests via the `Credentials` interface (implemented by `internal/auth.Resolver`: `x-api-key` header for API keys, `Authorization: Bearer` for OAuth sessions, with proactive refresh and a one-shot 401 refresh-replay in `DoWithReauth`). `dryrun.go` outputs the equivalent curl command when `--dry-run` is used. `upload.go` handles S3 presigned-URL uploads with a 500MB limit. |
| 42 | + |
| 43 | +### Authentication |
| 44 | + |
| 45 | +`internal/auth` implements OAuth sign-in against WorkOS AuthKit using the RFC 8628 device flow (`device.go`), an on-disk session store keyed by OAuth domain (`store.go`, `credentials.json` under `os.UserConfigDir()/wherobots/`, 0600, atomic writes), unverified JWT claim decoding for display (`jwt.go`), and the request-time credential resolver (`resolver.go`; env API key always beats a stored session). `auth login|logout|status` live in `internal/commands/auth.go` and are dispatched spec-free from `main.go` (see `commands.IsSpecFreeInvocation`), so they work with no credentials, cached spec, or API connectivity. Provisioning a new OAuth client is documented in `docs/oauth-setup.md`. |
| 46 | + |
| 47 | +### Key Packages |
| 48 | + |
| 49 | +| Package | Role | |
| 50 | +|---------|------| |
| 51 | +| `internal/commands` | Cobra command builders — both dynamic (builder.go) and curated (jobs.go) | |
| 52 | +| `internal/spec` | OpenAPI spec fetching, caching, and parsing | |
| 53 | +| `internal/executor` | HTTP request construction, execution, dry-run, file upload | |
| 54 | +| `internal/config` | Env-var-based configuration loading | |
| 55 | +| `internal/hints` | Schema-aware error messages for invalid arguments | |
| 56 | +| `internal/version` | Background update checking via `gh release view` | |
| 57 | + |
| 58 | +### Version Injection |
| 59 | + |
| 60 | +`main.go` has `buildVersion`, `commit`, `date` vars injected via ldflags at build time. Local builds show `dev`. |
| 61 | + |
| 62 | +## CI/CD |
| 63 | + |
| 64 | +- **PR validation** (`.github/workflows/pr-validate.yml`): runs `go test` and `go build` on every PR |
| 65 | +- **Release** (`.github/workflows/release.yml`): on push to main, builds all 6 platform binaries (darwin/linux/windows x amd64/arm64), generates SHA-256 checksums, publishes as rolling `latest-prerelease` GitHub release |
| 66 | +- **GoReleaser** (`.goreleaser.yaml`): configures cross-platform builds and archive formats |
0 commit comments