@freecodecamp/universe-cli
v0.6.0
Published
Static site deployment CLI for the freeCodeCamp Universe platform
Readme
Universe CLI
Static site deployment for the freeCodeCamp Universe platform.
Install
npm
# Run directly
npx @freecodecamp/universe-cli <command>
# Or install globally
npm install -g @freecodecamp/universe-cli
universe <command>Binary
# macOS (Apple Silicon)
gh release download --repo freeCodeCamp-Universe/universe-cli --pattern "universe-darwin-arm64"
chmod +x universe-darwin-arm64
sudo mv universe-darwin-arm64 /usr/local/bin/universe
# macOS (Intel)
gh release download --repo freeCodeCamp-Universe/universe-cli --pattern "universe-darwin-amd64"
chmod +x universe-darwin-amd64
sudo mv universe-darwin-amd64 /usr/local/bin/universe
# Linux x64
gh release download --repo freeCodeCamp-Universe/universe-cli --pattern "universe-linux-amd64"
chmod +x universe-linux-amd64
sudo mv universe-linux-amd64 /usr/local/bin/universe
# Linux ARM64
gh release download --repo freeCodeCamp-Universe/universe-cli --pattern "universe-linux-arm64"
chmod +x universe-linux-arm64
sudo mv universe-linux-arm64 /usr/local/bin/universeVerify:
universe --versionCLI surface
Top-level (cross-cutting):
universe login # GitHub OAuth device flow → ~/.config/universe-cli/token
universe logout # delete stored token
universe whoami # echo current login + authorized-sites count
universe --version # CLI versionStatic-site verbs (namespaced under static):
universe static deploy [--promote] [--dir <path>]
universe static promote [--from <deployId>]
universe static rollback --to <deployId>
universe static ls [--site <site>]Static-app registry (namespaced under sites, staff-gated writes):
universe sites ls [--mine] # list registered sites; `--mine` filters to your authorized set
universe sites register <slug> [--team=<name>...] # create new entry (staff; defaults --team to staff)
universe sites update <slug> --team=<name>... # replace teams list (staff)
universe sites rm <slug> # delete entry (staff; R2 deploy bytes untouched)All commands support --json for CI integration.
Identity (priority chain)
The CLI resolves a GitHub identity in this order — first match wins:
$GITHUB_TOKEN/$GH_TOKENenv (CI explicit)gh auth tokenshell-out (laptop withghinstalled)- Device-flow stored token at
~/.config/universe-cli/token
CI runners must export $GITHUB_TOKEN explicitly. artemis validates the bearer via GitHub GET /user, then authorizes server-side against the Valkey-backed registry. Run universe whoami to see which slot resolved; inspect the sites you can deploy to with universe sites ls --mine.
Configuration (platform.yaml)
Every site has a platform.yaml at its repo root. Minimal valid file:
site: my-siteFull schema reference (every field, defaults, validation rules): docs/platform-yaml.md.
No credential fields. The proxy holds the R2 admin key; the CLI never reads or writes one.
Common flows
Full operator walkthrough (login → deploy → promote → rollback, CI shape, registry admin, troubleshooting) lives in docs/STAFF-GUIDE.md.
Environment overrides
| Env | Default | Purpose |
| --------------------------- | -------------------------------- | --------------------------------------------------------- |
| UNIVERSE_PROXY_URL | https://uploads.freecode.camp | Override proxy host (staging etc.) |
| UNIVERSE_GH_CLIENT_ID | baked-in freeCodeCamp OAuth id | Override GitHub OAuth App id (fork tenants, login only) |
| GITHUB_TOKEN / GH_TOKEN | — | Slot 1 of identity chain |
The shipped binary embeds the freeCodeCamp GitHub OAuth App client id (public; device flow uses no client_secret), so universe login works out of the box for staff. Fork operators and self-hosted mirror tenants set UNIVERSE_GH_CLIENT_ID to their own OAuth App's id — env value wins when set.
