# rickub CLI `rickub` is the command-line interface to a [rickub](https://rickub.com) git host — *the smartest git in the universe, on the command line.* It is a thin, standalone HTTP client for the rickub JSON API (`/api/v1`), authenticated with a personal access token (PAT). It imports none of the server's code: a clean client boundary. - Repo: `ssh://git@rickub.com/rickub/cli.git` - Home: ## Install **Download a release.** Binaries for linux (amd64, arm64) and macos (amd64, arm64) are attached to each release at . Open that page, download the archive matching your OS and architecture, extract it, and put `rickub` on your `PATH`: ```sh # after downloading the asset for your platform from the releases page: tar -xzf rickub___.tar.gz rickub sudo install rickub /usr/local/bin/rickub ``` > Note: rickub.com serves release assets from the release page itself — there is > no `/releases/latest/download/…` redirect, so pick the asset from the page (or > from the release's API entry) rather than guessing a URL. **Build from source** (Go 1.26+): ```sh git clone ssh://git@rickub.com/rickub/cli.git cd cli go build -o rickub . # produces ./rickub at the repo root ``` To stamp a version into the binary: ```sh go build -ldflags "-X rickub.com/rickub/cli/cmd.Version=$(git describe --tags)" -o rickub . ``` Verify: ```sh ./rickub version ``` ## Authenticate ```sh # browser (device) flow — the default. Prints a code, opens your browser, # waits for you to approve the sign-in while logged in to the website, and # stores the PAT the server mints. Nothing is copy-pasted. rickub auth login rickub auth login --host https://dev.rickub.com # any rickub host rickub auth login --scope read # a read-only token rickub auth login --no-browser # print the URL, don't open it ``` To use an existing PAT from *Settings → Tokens* instead, prefer one of the two forms that keep the secret out of your shell: ```sh # 1. environment variable — nothing is written to disk export RICKUB_TOKEN=rickub_pat_xxx rickub repo list # 2. stdin, for `auth login` to verify and store it echo "$RICKUB_PAT" | rickub auth login --with-token --host https://rickub.com ``` There is also a `--token rickub_pat_xxx` flag on any command. Use it only when neither of the above fits: **arguments are visible to every process on the machine via `ps`, and land in your shell history and in CI logs.** The stored token lives in `~/.config/rickub/config.yaml` (mode `0600`). The browser flow mints a normal PAT named "CLI device login" — revoke it any time in Settings → Tokens. ```sh rickub auth status # show the active host, where the token came from, and verify it rickub auth logout # remove the stored token for the active host ``` ### Tokens are bound to their host A token stored by `auth login` is saved **under the host it was verified against** and is only ever sent back to that host. Pointing the CLI at a different server — `--host`, `RICKUB_HOST`, or a typo — will not hand your production credential to it; you get "no token stored for that host" instead. Log in per host as needed: ```sh rickub auth login --host https://rickub.com # stored for rickub.com rickub auth login --host http://localhost:3000 # stored separately rickub auth logout --host http://localhost:3000 # removes only that one ``` A token you pass explicitly with `--token` or `RICKUB_TOKEN` is always honoured for whatever host is in effect — that is your call to make, not the config's. The CLI also prints a warning to stderr before sending a token to a host over plain `http://`, unless that host is loopback (`localhost`, `127.0.0.1`, `[::1]`), where the request never reaches the network. ### Config & environment Effective host and token are resolved with this precedence (first wins): | Value | Precedence | |-------|-----------| | host | `--host` flag → `RICKUB_HOST` env → config file → `https://rickub.com` | | token | `--token` flag → `RICKUB_TOKEN` env → config file entry **for that host** | Point the CLI at a dev instance with `--host http://localhost:3000` (or set `RICKUB_HOST`). `XDG_CONFIG_HOME` is honoured for the config file location. The config file looks like this: ```yaml host: https://rickub.com hosts: https://rickub.com: token: rickub_pat_… http://localhost:3000: token: rickub_pat_… ``` ## Command reference Every command supports `--help`, and `--json` for raw JSON output instead of a table. ``` rickub auth login|status|logout rickub repo list [--user H | --org H] [--page N] [--per-page N] rickub repo create [--org H] [--public|--private] [-d desc] rickub repo view rickub repo edit [--visibility public|private] [-d desc] [--default-branch B] rickub repo delete [--yes] rickub repo clone [dir] [-- git-args…] rickub repo files [path] [--ref R] rickub repo cat [--ref R] rickub repo commits [ref] [--page N] [--per-page N] rickub repo compare rickub repo collaborator list rickub repo collaborator add [--permission read|write|admin] rickub repo collaborator remove rickub pr list [-R owner/repo] [--state open|closed|merged|all] rickub pr view [-R owner/repo] rickub pr create [-R owner/repo] --base B --head H --title T [-b body] [--head-owner O --head-repo R] rickub pr merge [-R owner/repo] [--method merge|squash|ff-only] rickub pr close [-R owner/repo] rickub pr comment [-R owner/repo] -b "text" rickub run list [-R owner/repo] rickub run view [-R owner/repo] rickub run logs [-R owner/repo] rickub run rerun [-R owner/repo] rickub run cancel [-R owner/repo] rickub run dispatch [-R owner/repo] [--ref B] rickub run watch [-R owner/repo] [--interval 2s] [--timeout 30m] [--logs] # follow until terminal; exit 0 on success, 1 otherwise rickub issue list [-R owner/repo] [--state open|closed|all] [--page N] rickub issue view [-R owner/repo] rickub issue create [-R owner/repo] -t "title" [-b "body" | -b - < file] rickub issue close [-R owner/repo] rickub issue reopen [-R owner/repo] rickub issue comment [-R owner/repo] -b "text" rickub issue label [-R owner/repo] --labels "bug,help wanted" | --clear rickub issue milestone [-R owner/repo] --milestone "v1.0" | --clear rickub issue assign [-R owner/repo] --user H [--remove] rickub issue labels [-R owner/repo] rickub milestone list [-R owner/repo] [--state open|closed|all] rickub milestone create [-R owner/repo] -t "v1.0" [-d desc] [--due YYYY-MM-DD] rickub milestone close [-R owner/repo] rickub milestone reopen [-R owner/repo] rickub milestone delete [-R owner/repo] rickub org view rickub org members rickub org teams rickub search repos [--page N] [--per-page N] rickub api [-f key=value] [-F key=value] # raw escape hatch rickub browse [owner/repo] [--print] rickub version ``` ### Repo selector `pr`, `run`, `issue`, and `milestone` subcommands take `-R/--repo owner/repo`. When omitted, the repo is inferred from the current directory's git `origin` remote (any of `https://`, `ssh://`, or `git@host:owner/repo` forms). ### `rickub api` — raw escape hatch Like `gh api`. `PATH` is relative to `/api/v1` (a leading `/api/v1` or `/` is optional). `--field/-f` values are type-inferred (`true`/`false`/`null`/numbers); `--raw-field/-F` forces a string. Fields become query parameters for `GET`/`HEAD` and a JSON body otherwise. ```sh rickub api GET /user rickub api GET search/repos -f q=api rickub api POST /repos -f name=demo -f visibility=public ``` ## Errors & exit codes API errors are surfaced from the `{error:{code,message}}` envelope, e.g. `rickub: repository not found (not_found)`, and the process exits non-zero. ## Pointing at a dev host ```sh # run a rickub instance on a spare port, then: echo "$DEV_PAT" | rickub auth login --with-token --host http://localhost:3000 rickub repo list --user ``` The dev token is stored separately from your rickub.com token; both stay put. ## Development ```sh go build ./... && go test ./... && go vet ./... && gofmt -l . ``` Layout: ``` main.go # entrypoint; maps API errors to exit codes cmd/ # Cobra command tree (auth, repo, pr, issue, milestone, run, org, search, api, browse) internal/api/ # typed HTTP client for the rickub JSON API internal/config/ # config load/save + host/token resolution and binding ```