extraorbital
v0.1.6
Published
Provision cloud resources from the command line and write their credentials to .env
Maintainers
Readme
extraorbital
Note: this is the CLI of a service under development — don't use it for production projects yet. Ping us at [email protected] if you think it can be useful to you!
Provision databases, storage, queues, and model keys in one command. Credentials land in .env.
npx extraorbital provision .Also available as eo after npm i -g extraorbital.
Autopilot
provision looks at the directory, finds variables it can fill, skips ones that already have a value, and creates the rest.
$ npx extraorbital provision .
Provisioning 2 resources for .
s3 S3_BUCKET +1 · used in src/upload.ts
mongo MONGODB_URI · declared in .env.example
Left alone: 1 variable that already has a value
✓ Created project cosmic-otter → .extraorbital.json
✓ Provisioned s3/default (bucket cosmic-otter-default, us-east-1)
✓ Wrote 5 variables to .env
S3_BUCKET, S3_ENDPOINT, S3_REGION, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY
✓ Provisioned mongo/default (database cosmic-otter-default, us-east-1)
✓ Wrote 1 variable to .env — MONGODB_URI
2 resources created · Prototype plan · no card requiredIt looks at, in order:
- keys in
.env.example,.env.sample, or.env.template - empty or placeholder values in
.env/.env.local(your-bucket, and the like) - the exact name in source (
process.env.MONGODB_URI,os.environ["MONGODB_URI"], any language)
--dry-run prints the plan and why each line is there. Everything is created at slug default.
One resource
npx extraorbital add mongodb
npx extraorbital add s3 ./web
npx extraorbital add redis --slug cacheSafe to re-run. The same project, service, and slug always return the same resource.
$ npx extraorbital add s3
→ s3/default already exists — returned existing credentials
→ .env unchangedWhat gets written
A fenced block, so later runs can update or remove it without touching the rest of the file:
# >>> extraorbital resource=s3 project=cosmic-otter slug=default
S3_BUCKET=cosmic-otter-default
S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=AKIA7F2A91C4E8B3D6QZ
S3_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEX
# <<< extraorbital resource=s3Writes go to --env-file, else .env.local if it exists, else .env. An empty MONGODB_URI= above the fence would win, so extraorbital comments that line out and tells you.
Resources
| Resource | Writes | Options |
| ------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| s3 | S3_BUCKET, S3_ENDPOINT, S3_REGION, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY | --region, --public |
| mongo (mongodb) | MONGODB_URI | --region |
| redis | UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN, REDIS_URL | --region |
| vector | UPSTASH_VECTOR_REST_URL, UPSTASH_VECTOR_REST_TOKEN | --dimensions, --embedding-model, --similarity-function, --region |
| qstash | QSTASH_URL, QSTASH_TOKEN, QSTASH_CURRENT_SIGNING_KEY, QSTASH_NEXT_SIGNING_KEY | — |
| openai | OPENAI_BASE_URL, OPENAI_API_KEY | --max-budget, --model-tier |
| anthropic | ANTHROPIC_BASE_URL, ANTHROPIC_API_KEY | --max-budget, --model-tier |
| git | GIT_URL, GIT_USERNAME, GIT_TOKEN | — |
| stripe | STRIPE_SECRET_KEY, NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, STRIPE_WEBHOOK_SECRET | — |
--max-budget is in dollars (--max-budget 10) and has no default — a paid key is uncapped unless you name a ceiling, since the account already has a budget cap of its own. --model-tier is small or full; on the Prototype plan the tier is forced to small and the budget is whatever is left of the $5.00 allowance. Options apply at creation and are ignored if the resource already exists.
git is experimental — good for agent state, not yet somewhere to keep the only copy of anything.
stripe is shared, and the only resource in the catalog that is: every project provisioning it gets the same test-mode keys to one Stripe account we run. No real money moves, but nothing you create in it is private or guaranteed to survive, and STRIPE_WEBHOOK_SECRET is only written where an endpoint is configured. The CLI prints the caveat next to the credentials, and GET /services marks the entry supply: "shared". Use your own keys before you take a real payment.
Project
A directory belongs to one team and project, stored in .extraorbital.json. Commit it — it is not a secret. After that, commands need no flags:
npx extraorbital init --team vercel --project skills.dev
npx extraorbital provisionprovision and add create a project if there isn't one. To move the directory:
npx extraorbital switch --team acme --project skills.devA --team or --project that disagrees with the file exits instead of writing into a different home.
npx extraorbital add mongodb --team vercel --project skills.dev --slug analyticsCommands
| Command | Does |
| -------------------------------- | ------------------------------------------------------- |
| provision [dir] | Create everything the project needs and is missing |
| add <resource> [dir] | Create one resource |
| list (ls) | Resources in the project |
| check [dir] | Verify each fenced block is healthy (--fix to repair) |
| remove <resource> [dir] (rm) | Delete the resource and its block |
| init [name] [dir] | Set the team and project |
| switch [dir] | Point this directory at another team or project |
| login · whoami | Sign in / see who you are |
| projects · teams | List, create, delete, add members |
| ledger (usage) | Spend this month |
| link · open | Enable billing / open the dashboard |
| help [command] | Flags for a command |
--yes skips confirmations. --no-env prints KEY=value to stdout and writes nothing. --json prints one JSON object to stdout.
Billing
Prototype allowances first. Past them, the command exits 3 with a URL a human opens to attach a card:
$ npx extraorbital add s3
! Your team has spent its Prototype allowance and cannot add s3. Move to a paid plan by
having a human open the link below — then you are billed only for what you use.
A human must link a payment method to continue:
https://extraorbital.dev/link/fl_8a2c91d4e7b3
Link expires in 24h · npx extraorbital link for a fresh URL
Exit code 3 (payment required)link mints that URL before anything is blocked. ledger shows spend.
Unattended
Nothing here waits for a human. The first run registers this machine — an Ed25519
keypair, kept in ~/.extraorbital/machine.json at mode 0600 — and provisions
against an account of its own on the Prototype plan. No browser opens and no
approval is requested.
A human becomes necessary only at the point money does: when the allowance runs out, the command exits 3 with the URL above, and whoever pays takes ownership of the account the agent built.
npx extraorbital provision .
npx extraorbital check --quiet || npx extraorbital check --fixKeep that file and the machine keeps its account and its spend. Lose it — a fresh
container, a wiped home directory — and the next run is a new machine with a new
account. Pass --token or EXTRAORBITAL_TOKEN when you want a specific identity
regardless, and --login when you want to attach your own.
| Code | Meaning |
| ---- | --------------------------------------------- |
| 0 | Success |
| 1 | Failure / check found something unhealthy |
| 2 | Bad usage (including a team/project mismatch) |
| 3 | Payment required — surface the printed URL |
| 4 | Not signed in, with --no-login set |
| 5 | Provisioning in progress — retry |
| 6 | Rate limited — wait, then retry |
| 7 | Upstream failure — retry |
Token for one run: --token or EXTRAORBITAL_TOKEN (never written to disk). To act
as yourself rather than as the machine, login once — or login --no-browser over
SSH, which prints the code instead of opening anything.
