Log in

xo login signs you in to XO in your browser and connects GitHub through gh. xo login --key takes a pasted XO API key instead.

Run xo login on its own line, not pasted together with other commands:

xo login

xo first prints the three services it logs in to, me, xo and github. Then:

  1. XO, in your browser. When the xo server offers browser login (https://xo.quirq.dev does), xo prints a link and opens it. Sign in to XO, and the browser comes back to xo on this machine (127.0.0.1). The xo server then sends xo your account's key: the one an earlier browser login made for you, or a new one that works for 90 days. If a key you saved before still works, xo says "already logged in" and skips this. A server without browser login, or a key piped in, gets the key prompt below instead. If the sign-in fails or does not come back within 5 minutes, xo saves nothing and exits 1.
  2. The quirq hub. When the xo server keeps a quirq hub, xo asks it for your hub agent, named after your XO username, and hands the agent's token to the hub's client, spacehub, which keeps it (install it first). xo saves only the hub's address and the agent's name, in ~/.config/xo/hub, and says xo: hub: agent NAME on https://hub.quirq.dev; .... Without spacehub it says skipped and how to install it: spaces then work with GitHub alone, and xo create space needs --github. A server with no hub says nothing here.
  3. GitHub, through gh. If the GitHub CLI (gh) is installed, xo checks that it is connected to github.com, and runs gh auth login in your browser if it isn't. xo never sees or saves the GitHub token: gh keeps it. Without gh, this step says skipped.

Each service ends with one line, such as xo: me: logged in as ... or xo: github: connected to github.com as .... One failure does not stop the others. Check where you are logged in with:

xo status

gh may ask "Authenticate Git with your GitHub credentials?". Yes (gh's default) makes gh git's login for github.com, which changes ~/.gitconfig or the login your system keeps for git (the Keychain on a Mac). Answer n to leave git as it is.

Paste a key instead

xo login --key

Use this when the browser can't come back to xo, or when the XO team gave you an XO API key. Paste the key at the XO API key (hidden: paste it, then press Enter): prompt. Nothing shows while you type, and the key stays out of your shell history. xo refuses anything that isn't an XO API key (those start with ak_) without sending it anywhere, then checks the key with XO, which can take up to a minute. Only a key that passes is saved. A saved key that still works wins here too: to replace it, run xo logout first.

Browser login and --key came with xo 436bfbe. If xo login --key stops with unrecognized arguments, your xo is older: update it.

Over SSH, the browser on your own machine cannot come back to the remote one. xo says so and prints the port: reconnect with ssh -L PORT:127.0.0.1:PORT <host> using that port, or use xo login --key.

Where the key is kept

xo saves the key and the address it logged in to in ~/.config/xo/credentials, which only you can read (on Windows, xo cannot limit who reads it, and says so). Every later command, in any terminal, uses that key and sends it only to that address. A key in XO_API_KEY wins over the saved one.

xo login xo       # only the XO key
xo login github   # only GitHub
xo logout         # deletes your XO key and the hub's address; asks before logging gh out

xo logout leaves spacehub's own login; spacehub auth logout ends it. Once xo saved a hub, xo status shows a fourth line, hub, with its address and your agent.

If GH_TOKEN or GITHUB_TOKEN is set in your terminal, gh uses that token instead of its own login, and xo says so.

Check it works

This creates nothing:

xo spaces --space-id 00000000-0000-0000-0000-000000000000

It should end with HTTP 404: Space not found: your key reaches XO Cloud. A 401 means XO does not know the key; run xo login again.

Next: create a space.