Create a space
Preview a create with --dry-run, then create a Claude Code, Codex or other space on XO Cloud, or make a folder of your git repositories a space on the quirq hub or GitHub.
A space is a collection of GitHub repos, and where an agent works on them on
XO Cloud. xo create space NAME KIND creates one on XO Cloud and records it in
your spaces as NAME. To make a folder of repos a space on the quirq hub (or
GitHub) instead, see A space from your folders.
1. See what a kind takes
xo create space --help # the kinds of space
xo create space NAME codex --help # the flags of one kind2. Preview it (sends nothing)
xo create space my-first-space codex --volume-size 20 --dry-runThis prints the request xo would send, a notice that a real create copies your
key into the space, then xo: dry run, nothing sent.
3. Create it for real
Before you create anything, know three things:
- XO Cloud can't delete, start or stop a space, and xo has no command for it. A space you create stays, so create only one you mean to keep.
- Every create except
nebius-openclawstores your XO API key inside the new space. xo prints a notice as the request goes out; it does not pause or ask first. Anything that can read the space's environment, an agent steered by a message for example, can act as you. If the XO team can give you a second key, use that one for creates. xo spaces --space-id IDprints URLs that carry a session token. Don't share them.
xo create space my-first-space codex --volume-size 20This creates the space on your account and records it in your spaces. To see it again, with its XO id, and then XO Cloud's own view of it with its connection URLs:
xo spaces
xo spaces --space-id THE_IDThe kinds
| Command | Creates |
|---|---|
xo create space N codex --volume-size 20 | a Codex space |
xo create space N antigravity --volume-size 20 | an Antigravity space |
xo create space N claude-code --volume-size 20 --providers-anthropic-api-key - | a Claude Code space (- asks for the key) |
xo create space N hermes …, … openclaw …, … xo-cowork … | spaces with providers and chat channels; see xo create space N openclaw --help |
xo create space N nebius-openclaw --token-factory-api-key - | a Nebius OpenClaw space (behind a feature flag; HTTP 404 when it is off for you) |
xo create space | the folder you are in as a space on the quirq hub, nothing on XO Cloud (below) |
xo create space N | the same for the folder ./N, made if it is not there |
xo create space N --github | the folder ./N as a space on GitHub instead (--gh too) |
- With a kind, N is 1 to 32 letters, digits or hyphens, starts with a letter
or digit, and can't be
neworcreate. XO keeps names in lowercase, soMyDevbecomesmydev, and xo says so. A name you already used fails. --volume-sizeis in GB, 20 to 100.- When you give a provider key or bot token as
-, xo asks for it without showing it. Only one-works per command. Put other secrets in a JSON file and pass it with--data @body.json(make it readable only by you, and delete it afterwards). Anything typed on the command line lands in your shell history. - If a create times out or is interrupted, XO may still have made the space:
check
xo spacesbefore you try again.
A space from your folders
With no kind, xo create space makes a folder a space, published on the
quirq hub: each git repository in it becomes its own branch, named by its
path (api, or work/api for one inside a plain folder work), and an
index branch lists them. A branch holds the repository's files as they are
now, not its history. Nothing is made on XO Cloud. With --github (or
--gh) it goes to GitHub instead (below).
- With no NAME, the folder you are in is the space, named after the folder (or the name xo gave its space before).
- With NAME, the folder
./NAMEis the space. When there is no./NAME, xo makes it, and takes it away again if you say no or the run stops before the space is built. The new space is empty until you put git repositories in it and runxo create spaceagain there.
For example, a space of two well-known Python repos:
mkdir web && cd web
git clone https://github.com/pallets/flask
git clone https://github.com/psf/requests
xo create space # space web, on the quirq hub: branches flask and requestsAnyone can read the hub in this version, and what is pushed stays there.
xo never deletes a branch and never force-pushes, so a file you take out
later is still in the history, and a repository you remove keeps its
branch. xo leaves out .env files, keys and credential stores, and stops
before pushing a file that looks like it holds a key, token or password,
but it cannot find every secret (one in an archive, say). Look through the
repositories before you say yes.
- xo lists each repository with its size and where it goes, and asks first.
--yesanswers that question for you (but not the hub's typed name or GitHub's link, below). - When the folder has no
.git, xo makes a bare./.gitbeside your folders, so nothing in them changes, andmainis the index. - When the folder is already a git repository, xo adds the space to it:
one branch per repository in it, and the index on a branch
xo-space. Your branches, checkout, files and staged changes stay as they are. xo only moves or deletes a branch it made, and only while it is where xo left it: commit on one or check it out, and xo never touches it again (and refuses the repository whose branch it was). It refuses when a repository's branch would clash with one of your branches (here or on GitHub, in any case), when there is already anxo-spacebranch xo did not make, and when the folder is a worktree or submodule of another repository. - xo looks for repositories up to 6 folders down: a clone, or a worktree or
submodule whose
.gitis a file. Folders that are not repositories and hold none, files outside the repositories, hidden folders, links to folders,node_modules,venvand__pycache__are not part of the space. A repository inside another one is not a branch of its own: it is left out of the outer one's files. - The space folder's
.gitignoreis followed, and can leave out whole folders (xo lists them), and so is each repository's own.gitignoreand.git/info/exclude..envfiles, keys, credential stores,node_modules,.DS_Storeand Terraform state are always left out, as is.github/workflows. A file over 100 MB, a Git LFS pointer, a file git-crypt keeps encrypted or a bare repository among the files stops it before anything is pushed. - Each folder name on a repository's path is letters, digits,
_,.or-, starting with a letter or digit (notHEAD, no.., and not ending in.,.lockor_HEAD), and the path can't start with a folder calledmainorxo-space. Two repositories whose paths differ only in case are refused, since GitHub can't keep their branches apart. - Run
xo create spaceagain in the space's folder to push what changed (with--githubfor a space on GitHub). - It refuses your home folder and the folders above it (
/too), a hidden folder of your home or anything in one (such as~/.config),~/Libraryand~/AppDataand anything in them, a folder holding.ssh,.aws,.gnupg,.kube,.docker,.azure,.password-storeor.config/gcloud, a git repository's own.gitfolder, a bare repository xo did not make, a folder inside a git repository, and a repository that uses SHA-256 object names, which GitHub does not take. - The space's name is 1 to 64 letters, digits,
_,.or-, starts with a letter or digit, doesn't end in.git, and can't be a kind's name,neworcreate; with no NAME, the folder's name must fit too. It is lowercased, as on XO and GitHub. This form takes no--dry-run.
On the quirq hub
- It needs the hub's client,
spacehub, and anxo loginthat found the hub (install it). Without them xo stops before making anything and says so;--githubstill works. - The space is the hub project AGENT/NAME, in your hub agent's own space,
quirq://hub.quirq.dev/AGENT/NAME, made there when it is missing. The./.gitxo makes gets aquirqremote; in a folder that was already a git repository, xo pushes by URL and leaves its remotes alone. Nothing goes to GitHub. - Since anyone can read the hub, xo refuses the folder, or a git repository
in it, whose
originis not a GitHub repository anyone can read. Flask and Requests above are fine. - A repository with no
origin, or whose branch holds a file that is not in its last commit, or whose last commit is on no branch GitHub has, goes there only when you type the space's name at the terminal.--yesdoes not answer that, so without a terminal nothing is pushed. - A name with
--in it is refused: the hub keeps those for copies of GitHub projects (OWNER--REPO). For a space already on GitHub, xo stops before making anything and asks for--github, which updates it there.
On GitHub instead
--github (or --gh) puts the space on GitHub, under your gh login;
--owner OWNER picks another owner and implies --github. The repository is
public: anyone can read it, and what is pushed stays public.
xo create space --github # in ./web: space web, on github.com/YOU/web- The repository is
github.com/OWNER/NAME, OWNER being your gh login or--owner; with neither, xo stops and says so. In a folder that was already a git repository with an origin, it is the GitHub repository that origin is, and--ownermust agree; an origin that is not on GitHub, or has a login in it, is refused. xo checks the repository with no login, so a private origin looks missing to it: what is pushed there is as private as that repository, and a later run cannot update it. When the repository is not there, xo prints a link to make it (empty, with no README, public) and, at a terminal, waits for Enter, then pushes with your own git. The space goes in your spaces once it is pushed. --yesdoes not make the repository: without a terminal xo cannot wait for you, so when the repository is not there yet it stops before pushing (and still exits 0). Run it again once the repository exists. If it stops at the GitHub step, run it again in the folder to push it.
Next: put your projects in a space.