What a config is
A space config is one version-1 TOML document. It holds everything a new space starts with. The name and icon on its card, whether the space runs in a container, which repository it checks out, the panes and tabs it opens, the variables it asks for, and the scripts it runs around the space lifecycle. Save as config in a running space's menu exports that space into one of these documents, and the Team's Space configs page is where you edit it. Every space created from a config is an independent copy, so editing the config later never changes a space already running.
The document
Top-level keys describe the config itself. Everything else lives in a table below them. Unknown keys are rejected by name, so a typo fails loudly instead of being ignored.
| Key | Type | Description |
|---|---|---|
| version | integer | The file format version. Omit it, or set it to 1. |
| label | string | The name shown on the config card and given to spaces created from it. Required. |
| description | string | One line shown beside the label. |
| icon | string | An Iconify id such as mdi:code-braces, or a custom SVG as a base64 data URI. |
| incognito | boolean | Disables memory capture along with activity and content recording. |
| memory_disabled | boolean | Disables memory capture without the rest of the incognito behavior. |
| skills | array of strings | The exact set of agent skill ids a space starts with. |
version = 1
label = "API service"
description = "An agent, a shell, and a live preview"
icon = "mdi:server"
[repository]
url = "https://github.com/example/api"
[[pane]]
width = 2
[[pane.tab]]
label = "Agent"
type = "server"
command = "clor webagent serve"
[[pane]]
width = 1
[[pane.tab]]
label = "Shell"
command = "bash --login"
Sandbox
The [sandbox] table asks for a container. Omit the table and the space runs directly on the runner's host. The reserved image name default selects Clor's managed image, which already carries the agent runtimes and the usual development tools. Resource keys are placement requirements, so they decide which runner can host the space rather than reserving capacity on it.
| Key | Type | Description |
|---|---|---|
| image | string | The container image. The reserved name default selects Clor's managed image. Required whenever the table is present. |
| user | string | The account that runs space commands, optionally account:group. |
| docker_access | boolean | Gives the space its own private Docker daemon for Docker, Compose, and Testcontainers work. |
| isolation | string | privileged, standard, strict, or maximum. Empty applies the runtime default. A runner that cannot honor the level refuses the space. |
| memory_mb | integer | Whole-megabyte memory requirement. Zero applies 512. |
| disk_gb | integer | Whole-gigabyte disk requirement. Zero applies 1. |
| memory_limit_mb | integer | A hard container memory limit. Zero means no limit. |
| gpu | string | none, optional, or required. Empty means none. |
| restart | string | always, on_failure, or never. Empty applies the runtime default. |
| [[sandbox.mount]] source | string | The host path to bind into the container. |
| [[sandbox.mount]] target | string | The path the bind appears at inside the container. |
| [[sandbox.mount]] required | boolean | A missing source fails the space startup instead of being silently skipped. |
| [[sandbox.mount]] read_only | boolean | Binds the mount read-only. |
[sandbox]
image = "default"
user = "user"
docker_access = true
isolation = "standard"
memory_mb = 4096
disk_gb = 20
gpu = "none"
restart = "on_failure"
[[sandbox.mount]]
source = "/opt/models"
target = "/models"
read_only = true
required = true
Repository and directory
A config declares at most one source location. Use [repository] to clone a Git remote, or [directory] to work in a path that already exists on the runner's host. Declaring both is rejected, and a host directory cannot be combined with a sandbox, because its path names the runner filesystem. Both are presets, so whoever launches the space can point it somewhere else unless the config marks the slot required.
| Key | Type | Description |
|---|---|---|
| [repository] url | string | The clone URL. Leave it empty to ask at launch. |
| [repository] default_name | string | Advises the New space page which of your repositories to preselect for an empty slot. |
| [repository] branch | string | An existing branch, tag, or commit to check out. Empty uses the remote's default branch. |
| [repository] branch_mode | string | default, existing, or new. default takes the remote head, existing requires branch, and new requires new_branch. |
| [repository] new_branch | string | The local branch to create from the remote head. Requires branch_mode set to new. |
| [repository] shallow | boolean | Requests a depth-one clone instead of the full history. |
| [repository] required | boolean | Prevents a launch from choosing the home directory instead of a repository. |
| [directory] path | string | The host path to work in. Empty selects the runner user's home directory. |
[repository]
url = "https://github.com/example/api"
branch_mode = "new"
new_branch = "feature-work"
shallow = true
required = true
Panes and tabs
Panes tile the space into columns. Each [[pane]] opens a new column unless it sets stack, which places it beneath the previous pane instead. Width is the column weight and height is the row weight inside a column, so the example below splits the space two to one. Every [[pane.tab]] declares exactly what it runs. A terminal tab runs its command line inside a browser terminal, a server tab runs the command directly and expects it to bind $CLOR_TAB_ADDRESS, and a port tab carries no command and fronts whatever already listens on the port. Leave type empty and a tab with a command is a terminal while a tab with only a port is a port tab.
| Key | Type | Description |
|---|---|---|
| [[pane]] slug | string | A stable identifier for the pane. Empty assigns a positional slug. |
| [[pane]] width | integer | The column weight, set on the pane that opens a column. |
| [[pane]] height | integer | The row weight within a column, usable on any pane. |
| [[pane]] stack | boolean | Places this pane beneath the previous pane's column instead of opening a new one. |
| [[pane]] minimized | boolean | Opens the pane collapsed to its header strip. At least one pane must stay open. |
| [[pane]] maximized | boolean | Opens the pane filling the space. At most one pane per config, and never alongside minimized. |
| [[pane.tab]] slug | string | A stable identifier for the tab. Empty assigns a positional slug. |
| [[pane.tab]] label | string | The text shown in the tab strip. |
| [[pane.tab]] type | string | terminal, server, or port. |
| [[pane.tab]] port | integer | The space port a port tab fronts, from 1 to 65535. |
| [[pane.tab]] command | string | The shell command line the tab runs. The shell expands it, so it may reference the tab environment. |
| [[pane.tab]] initial_prompt | string | The tab's opening prompt, delivered as CLOR_INITIAL_PROMPT. A command tab that authors none receives the launch prompt instead. |
| [[pane.tab]] system_prompt | string | The tab's system prompt, delivered as CLOR_SYSTEM_PROMPT. |
| [[pane.tab]] working_directory | string | Where the command runs. Only meaningful with a command. |
[[pane]]
slug = "agent"
width = 2
[[pane.tab]]
slug = "agent"
label = "Agent"
type = "server"
command = "clor webagent serve"
system_prompt = "Prefer small, reviewable commits."
[[pane]]
slug = "tools"
width = 1
[[pane.tab]]
slug = "shell"
label = "Shell"
type = "terminal"
command = "bash --login"
[[pane.tab]]
slug = "preview"
label = "Preview"
type = "port"
port = 3000
Environment variables
Each [[env]] table declares one variable in exactly one of four modes. A fixed value ships with the config. A required prompt asks at launch and will not create the space while it is blank. An optional prompt asks and accepts a blank answer. A secret reference names a value stored with clor secret, which is resolved on the runner and never copied into the config. Setting more than one of value, required, and secret on the same entry is rejected, and a name may not repeat.
| Key | Type | Description |
|---|---|---|
| name | string | The variable name. Required, and unique across the document. |
| value | string | A fixed value stored in the config. |
| required | boolean | Asks at launch and will not create the space while the variable is unset. |
| secret | string | The name of a stored secret, resolved at run time. |
[[env]]
name = "SERVICE_PORT"
value = "3000"
[[env]]
name = "API_TOKEN"
required = true
[[env]]
name = "FEATURE_FLAGS"
[[env]]
name = "DATABASE_URL"
secret = "production/database-url"
Setup script
The setup script runs once, after the space environment comes up, in the space working directory. It is where dependency installs, tool setup, and scaffolding belong, so an agent opens onto a project that is already ready to build and test. Write it as a TOML multi-line literal string with triple single quotes, which keeps backslashes and dollar signs exactly as typed. A single script may be at most 16 KiB.
[scripts]
setup = '''
set -o errexit
npm ci
npm run build
'''
Archive script
The archive script runs before teardown, and it is where a save-my-work step belongs. Pushing the working branch, uploading a build artifact with clor drive, or writing a summary somewhere durable all go here, because a space's local filesystem does not outlive it. Like setup it is capped at 16 KiB.
[scripts]
archive = '''
set -o errexit
git add --all
git commit --message "Work in progress" || true
git push --set-upstream origin HEAD
clor drive upload ./dist/report.html reports/report.html
'''
Agent recommendations
The [agents.claude] and [agents.codex] tables recommend a saved agent config by name for each runtime. A launch honors the recommendation when you have not pinned a choice of your own. Credentials are deliberately absent. They are personal launch state chosen by the member, and they never appear in this file.
| Key | Type | Description |
|---|---|---|
| [agents.claude] config | string | The saved Claude agent config to recommend. |
| [agents.codex] config | string | The saved Codex agent config to recommend. |
[agents.claude]
config = "claude-standard"
[agents.codex]
config = "codex-standard"
Routes
Each [[route]] table declares how one space port should be reachable. Host and path narrow an HTTP route and are rejected on a tcp or udp route. A port tab is the usual way to reach a service in the browser, while a route describes how traffic arriving at the runner should reach the space.
| Key | Type | Description |
|---|---|---|
| protocol | string | tcp, udp, or http. |
| port | integer | The target space port, from 1 to 65535. |
| host | string | The HTTP Host header to match. Empty matches every host. HTTP only. |
| path | string | The HTTP path prefix to match. HTTP only. |
| bind_address | string | The host interface the route binds to. |
[[route]]
protocol = "http"
port = 3000
path = "/api"
bind_address = "127.0.0.1"
Create one from an agent
The whole format is reachable from the command line, so an agent can author, review, and update a config without opening a browser. Export prints canonical TOML to standard output, create adds a new config from a file, and import replaces an existing config atomically.
Export this space as a config, add an archive script that pushes the branch, and import it back.
clor space config list
clor space config export <ID> > config.toml
clor space config create config.toml
clor space config import <ID> config.toml
clor space config delete <ID>Limits
A config file is at most 128 KiB, and each script inside it is at most 16 KiB. Unknown keys are rejected by name rather than ignored. A document declares one repository or one directory, never both, and it must declare at least one pane.