CLI reference
Every extraorbital command — provision, add, list, check, remove, switch, ledger, link.
AI/LLM: this page is available in plain markdown at /docs/cli.md
Run ad hoc with npx extraorbital, or install with npm i -g extraorbital (aliased
to eo). Node 20 or later, and no runtime dependencies. Examples below use the npx
form; if you installed it, drop the prefix.
No sign-in is required to start. The first run registers the machine with a
keypair and provisions against an account of its own on the Prototype plan — no
browser, no approval. A human is needed only when the allowance runs out and
somebody has to pay, at which point they take ownership of that account. Run
login if you would rather the resources belong to you from
the outset.
Credentials live in ~/.extraorbital/: the machine keypair in machine.json, a
human session in credentials.json, both at mode 0600 inside a 0700 directory,
and the CLI refuses to use either if the permissions are looser. The team and
project a directory belongs to live in .extraorbital.json, which is a pointer
rather than a secret and is safe to commit:
{
"projectId": "skills.dev",
"teamId": "team_9c1f77a2_vercel",
"server": "https://extraorbital.dev"
}Commands
| Command | Does |
|---|---|
provision [dir] | Provision everything the project needs and is missing |
add <resource> [dir] | Provision one named resource |
list | Every resource in the project |
check [dir] | Verify each fenced block against a live resource |
remove <resource> [dir] | Deprovision and delete its block |
init [name] [dir] | Set the team and project pair up front |
switch [dir] | Point this directory at another team or project |
login · whoami | Identity |
projects · teams | Manage what resources belong to |
ledger · link · open | Spend, billing, dashboard |
extraorbital provision
Reads the directory, works out which supported variables have no value yet, and provisions exactly those. Idempotent: a second run provisions nothing.
npx extraorbital provision [dir] [--dry-run] [--yes] [--no-env]Provisioning 2 resources for .
mongo MONGODB_URI · declared in .env.example
s3 S3_BUCKET +4 · used in src/upload.ts
✓ Provisioned mongo/default (database skills-dev-703c90-default)
✓ Wrote 1 variable to .env — MONGODB_URI
✓ Provisioned s3/default (bucket skills-dev-703c90-default, us-east-1)
✓ Wrote 5 variables to .env
2 resources created · no card requiredNothing there asked for payment, and nothing will until the account passes its free allowance — see pricing.
| Flag | Default | Description |
|---|---|---|
[dir] | . | Directory to read and write in |
--dry-run | off | Print the plan and the reason for each line, change nothing |
--yes, -y | off | Skip the confirmation prompt at an interactive terminal |
--no-env | off | Print credentials to stdout, write nothing |
The three signals it reads, and what it skips, are in how autopilot decides. It never prompts when stdin is not a terminal, so an agent or a CI job runs it unattended.
Everything is provisioned at slug default. A second instance is a deliberate add.
extraorbital add
Provisions one resource and writes its credentials. Idempotent on
(team, project, service, slug), so it is safe in a loop, a retry or on every boot.
npx extraorbital add <resource> [dir] [--slug <name>] [--team <slug>] [--project <id>] [options]| Flag | Default | Description |
|---|---|---|
<resource> | — | s3, mongo (or mongodb), redis, vector, qstash, authlocker (or auth), ai (the AI Gateway), git, stripe |
[dir] | . | Directory to write in |
--slug | default | A named second instance in the same project |
--team | from .extraorbital.json | Refused when it disagrees with a pinned pair |
--project | from .extraorbital.json | Refused when it disagrees with a pinned pair |
--no-env | off | Print credentials to stdout, write nothing |
Resource options come from the server's catalog rather than being hardcoded, so a new
service needs no CLI release: --region, --public, --dimensions,
--embedding-model, --similarity-function, --max-budget, --model-tier.
Amounts are in dollars, so --max-budget 10 is ten dollars. Each is documented
on its resource page.
Running it twice is not an error:
→ s3/default already exists — returned existing credentials
→ .env unchangedextraorbital list
Every resource in the project, including ones other machines provisioned. Aliased to
ls.
npx extraorbital list [--all] [--project <id>] [--json] skills.dev · 4 resources · $4.99 this month
RESOURCE STATUS CREATED BY CREATED THIS MONTH
s3/default active brave-fox-a3f2 Aug 1 09:14 — (not metered)
mongo/analytics active brave-fox-a3f2 Aug 1 09:20 — (not metered)
redis/default active steady-crane-77e1 Aug 2 14:41 — (not metered)
openrouter/default active brave-fox-a3f2 Aug 3 11:02 $4.99 (budget $10.00)extraorbital check
Verifies that every fenced block in .env and .env.local maps to a live resource
whose credentials still authenticate. Exit 0 means the whole environment is good,
which makes it the ideal first line of an agent's boot script.
npx extraorbital check [dir] [--fix] [--quiet] [--json]✓ s3/default credentials valid (reachable in 91ms)
✓ mongo/analytics credentials valid (reachable in 142ms)
✗ redis/default resource removed on Jul 28
Fix with: extraorbital add redis --slug default
2 of 3 healthy · exit code 1--fix re-provisions what is missing and rewrites the block in the file it came from.
extraorbital remove
Deprovisions a resource and deletes its fenced block. Stateful resources keep data
recoverable for seven days. Aliased to rm, and requires --yes when stdin is not a
terminal.
npx extraorbital remove <resource>/<slug> [dir] [--yes] [--force]✓ Removed mongo/analytics (recoverable until Aug 12)
✓ Removed MONGODB_URI block from .envextraorbital init
Sets the team and project pair once, so later commands take no flags. Optional:
provision and add create a project when there is none.
npx extraorbital init [name] [dir] [--team <slug>] [--label <label>]npx extraorbital init --team vercel --project skills.dev
npx extraorbital init scraper-prodextraorbital switch
Points this directory at another team or project, and the only way to change the pinned pair. Any flag you leave out keeps its current value.
npx extraorbital switch [dir] [--team <slug>] [--project <id>] [--create]npx extraorbital switch --team acme
npx extraorbital switch --project skills.dev
npx extraorbital switch --project brand-new --createExisting resources stay where they are: switch changes what this directory points
at, not what a resource belongs to.
extraorbital login
Signs a human in, with a device-code flow that works over SSH and inside
containers. It is never implicit: a command that needs an identity and has none
registers the machine instead, so an agent is never blocked waiting for a browser.
Use this when you want the resources to belong to your account rather than to the
machine's — or --login on any command to do it in one step.
npx extraorbital login [--token <token>] [--no-browser] [--logout] Open https://extraorbital.dev/device and enter code HXKD-9F2A
⠋ Waiting for confirmation…
✓ Signed in as severin
Token cached in ~/.extraorbital/credentials.json| Flag | Description |
|---|---|
--token <token> | Skip the browser and use a token directly. For CI. Also read from EXTRAORBITAL_TOKEN |
--no-browser | Print the URL instead of opening a browser |
--logout | Delete the cached credentials |
extraorbital whoami
user severin
namespace swift-heron-9c1f
machine brave-fox-a3f2
team vercel (owner)
project skills.dev (.extraorbital.json)
plan prototype · no human linked
token expires in 6dextraorbital projects
npx extraorbital projects # list
npx extraorbital projects new <name> # create without pointing at it
npx extraorbital projects rm <name> --yes # delete; refuses while resources remainUse switch --project to point a directory at one.
extraorbital teams
Everyone has a default team; these exist for when you want more than one, or want to share resources with a person or a fleet.
npx extraorbital teams # list
npx extraorbital teams new <slug> [--name "…"] # create
npx extraorbital teams members [--team <slug>] # who is in it
npx extraorbital teams add-member <email> [--role admin|member] TEAM ROLE MEMBERS PROJECTS RESOURCES THIS MONTH CREATED
▸ default owner 1 3 5 $5.40 Aug 1
scraper-fleet owner 3 1 2 $0.41 Aug 4
▸ current team · extraorbital switch --team <slug> to move this directoryextraorbital ledger
Spend, in the terminal, with graphs. Defaults to the current month grouped by project.
Aliased to usage. Bars are block characters so they paste cleanly into an issue; a
non-TTY gets a plain table.
npx extraorbital ledger [--group-by <dim>] [--month <yyyy-mm>] [--items] [--csv|--json] August 2026 · namespace swift-heron-9c1f
$5.40 this month $0.19/day avg · projected $5.89
skills.dev ████████████████████████████ $4.99
lunar-moth ██ $0.41
└─────────────────────────────────┘
$0 $5
DAILY Aug 1 ──────────────────────────── Aug 14
▁▃▂▅▇▆▄▃▅█▆▄▃▂▄▅▇█▆▅▃▂▁▂▃▅▆▇█▆▄▂
Prototype allowance covers $5.00 of this · $0.40 billable · extraorbital link| Flag | Default | Description |
|---|---|---|
--group-by <dim> | project | project, resource, service, machine, day, metric |
--month <yyyy-mm> | current | Billing month |
--from / --to | — | Explicit ISO range, overrides --month |
--project, --resource | all | Filters |
--items | off | Line items instead of an aggregate |
--csv / --json | — | Export formats |
--no-graph | off | Plain table. Implied when stdout is not a TTY |
extraorbital link
Prints the URL a human opens to move the team to a paid plan, lifting every free ceiling. The agent never sees or handles payment details. See When a human is needed.
npx extraorbital link
# → https://extraorbital.dev/link/fl_8a2c91d4e7b3extraorbital open
Opens the dashboard, deep-linked to where you are.
npx extraorbital open # the current project
npx extraorbital open ledger # /spend
npx extraorbital open project lunar-moth
npx extraorbital open resource s3/defaultGlobal flags and environment
| Flag | Env | Default |
|---|---|---|
--server <url> | EXTRAORBITAL_SERVER_URL | https://extraorbital.dev |
--token <token> | EXTRAORBITAL_TOKEN | cached credentials |
--team <slug> | EXTRAORBITAL_TEAM | from .extraorbital.json |
--project <id> | EXTRAORBITAL_PROJECT_ID | from .extraorbital.json |
--env-file <path> | EXTRAORBITAL_ENV_FILE | .env.local if it exists, else .env |
--json | — | Machine-readable output on stdout, logs on stderr |
--quiet / --verbose | — | normal |
--no-color | NO_COLOR | colour when a TTY |
--login | — | Sign a human in first, instead of using this machine |
--no-login | — | Exit 4 rather than registering this machine |
Reads look at both .env and .env.local; writes go to one file. A project that has
a .env.local gets its credentials there, because it has already decided that is
where secrets live.
Exit codes
Distinct codes so a supervising agent can branch without parsing text.
| Code | Meaning | The agent should |
|---|---|---|
0 | Success | Continue |
1 | Generic failure, or check failed | Read stderr; likely re-run with --fix |
2 | Usage error, including a pinned-pair conflict | Fix the command; do not retry as-is |
3 | Payment required | Surface the link URL to a human and wait |
4 | Not authenticated, with --no-login set | Supply a token, or drop the flag and let the machine register |
5 | Provisioning in progress | Retry with backoff; another worker holds the lease |
6 | Rate limited | Respect Retry-After |
7 | Upstream provider failure | Retry; the resource is left retryable |
Agents and CI
Non-interactive by construction: pass a token, get JSON, branch on exit codes.
#!/usr/bin/env bash
set -euo pipefail
# Idempotent: provisions on first boot, no-ops afterwards.
npx extraorbital provision .
npx extraorbital check --quiet || npx extraorbital check --fixnpx extraorbital provision --json | jq -r '.provisioned[].resource'
# mongo/default
# s3/default