Skip to content

CLI reference

One binary, promigence. Output is text on a terminal and a single JSON document everywhere else, so piping it into an agent needs no flags.

Install and run
bash
$ npm i -g ./promigence-<version>.tgz   # the file we sent you; not on npm yet
$ promigence signup                       # asks for your invite code
$ promigence run --snapshot promigence/base --count 2 --cap 1 --json -- python3 -c 'print(6*7)'
Language: bash

Global flags

--json

one JSON document on stdout; the default whenever stdout is not a TTY, except for exec --sandbox

--text

human-readable text

--api-key KEY

precedence: --api-key > PROMIGENCE_API_KEY > ~/.config/promigence/credentials

--version

print the version

--help

help; promigence <command> --help for one command

Setup

Sign up, check the install, and get an agent oriented in about 1,200 tokens.

promigence login

sign up or sign in (email; GitHub/Google where enabled); stores a new API key

--provider NAME
a sign-in method the API offers (email; github|google where enabled): skip the chooser
--no-browser
headless: print the URL, paste the code back
--key-name N
label for the key this login mints (default cli@<host>)
--api-url URL
sign in to this API instead of the default (no prompt)
--yes
accept a non-default API from PROMIGENCE_API_URL without the prompt
--ref CODE
a referral code (new accounts)
--json
force the JSON envelope

promigence signup

create an account (asks for an invite code first while invite-only)

--invite CODE
the code (prefer the prompt; argv is visible)
--provider NAME
a sign-in method the API offers (email; github|google where enabled): skip the chooser
--no-browser
headless: print the URL, paste the code back
--key-name N
label for the key this sign-in mints (default cli@<host>)
--api-url URL
sign up on this API instead of the default (no prompt)
--yes
accept a non-default API from PROMIGENCE_API_URL without the prompt
--ref CODE
a referral code (new accounts)
--json
force the JSON envelope

promigence logout

forget this CLI's key (revoked when promigence login minted it)

--keep-key
only forget it locally; the key keeps working
--json
force the JSON envelope

promigence auth login

store an API key (--from-env VAR | stdin; never on argv)

--from-env VAR
read the key from an environment variable
--api-key K
accepted but warns: key on argv

promigence keys list

your org's API keys

--all
include revoked keys
--project P
another project's
--org ORG
with --project: in this org
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence keys create

mint a key (secret printed once)

--name N
label, e.g. ci-prod
--org ORG
in this org (default: this key's)
--project P
in this project
--service
owners: outlives your membership (CI)
--expires WHEN
30d, 1y, a date; default never
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence keys revoke KEY_ID

revoke a key

--project P
a key in another project
--org ORG
with --project: in this org
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org list

your organizations (* = default)

--all
every one
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org create NAME

create one you own (no trial credit)

--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org switch ORG

sign in, make ORG the default, store a key for it

--project P
the new key's project
--keep-old-key
keep the replaced key working
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org members

members and roles

--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org invite EMAIL

invite an email (owners)

--role R
owner|member (member)
--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org invites

pending invites (14-day expiry)

--mine
sent to you
--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org uninvite INVITE_ID

revoke an invite (owners)

--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org role USER_ID ROLE

set owner|member (owners)

--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org remove USER_ID

remove a member; their keys die (owners)

--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org leave [ORG]

leave an organization

--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org join INVITE_ID

accept an invite sent to you

--decline
decline it instead
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org audit

who did what (owners; needs --sign-in)

--before SEQ
older entries
--limit N
how many (100)
--org ORG
another org than this key's
--sign-in
sign in in your browser: the log is read as you, never with a key
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence org delete ORG

delete it; keys die (owners)

--confirm NAME
its name (required)
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence project list

projects (keys belong to one)

--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence project create NAME

create a project

--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence project rename PROJECT NAME

rename (not default)

--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence project delete PROJECT

delete an empty one (owners)

--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence project cap PROJECT USD|off

monthly USD cap, or off (owners)

--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence project move PROJECT

to another org; keys die (owners)

--to ORG
yours, with a card
--org ORG
another org than this key's
--no-browser
sign in headless (or PROMIGENCE_ID_TOKEN)
--yes
sign in to PROMIGENCE_API_URL without the prompt
--json
force the JSON envelope

promigence me

plan, concurrency in use, trial credit, spend, limits

--json
force the JSON envelope

promigence billing card

add a card: prints a checkout URL (trial credits kept)

--json
force the JSON envelope

promigence doctor

check client, auth and API

--json
force the JSON envelope

promigence init

write promigence.toml

--repo U
git URL (default: the origin remote)
--commit SHA
commit to pin (default: HEAD)
--setup CMD
override the inferred setup step
--verify CMD
override the inferred verify command
--tier xsmall|small|medium|large|xlarge|2xlarge
default medium
--force
overwrite an existing promigence.toml
--print
write nothing; print what it would write
--json
force the JSON envelope

promigence examples

what forks with no build (no auth)

--limit N
how many to list (default 20)
--bundle
write each public snapshot as a .promigence file (none yet)
--json
force the JSON envelope

promigence agent-guide

~1.2k-token guide for agents (--section commands|errors|cost)

--section commands|errors|cost
one section instead of the core
--code C
the entry for one error code
--format md|json
default md
--install
write the fence into AGENTS.md/CLAUDE.md, .claude/skills, .cursor/rules
--create
with --install: create AGENTS.md if neither file exists
--check
report what --install would change; write nothing

promigence mcp

MCP server on stdio: claude mcp add promigence -- promigence mcp (Windows: -- cmd /c promigence mcp)

--read-only
offer only the tools that read: list, read a file, fetch output, a report
--allow-tools A,B
offer only these tools (comma-separated names)
--cap USD
spend cap for every sandbox and batch it starts (else PROMIGENCE_SPEND_CAP, else the org default)
--keep
leave the sandboxes this session created running at shutdown

promigence status

regions · your concurrency in use vs your limit

--json
force the JSON envelope

promigence billing usage

this month's spend: plan, usage by tier, credits, next invoice

--ledger
also print this key's project's metered rows
--limit N
with --ledger: how many rows (default 20)
--cursor C
with --ledger: the next_cursor of an earlier page
--json
force the JSON envelope

promigence referrals

your referral code, its offer, your referrals

--json
force the JSON envelope

promigence referrals apply <code>

apply a code (owner, before the first paid invoice)

--json
force the JSON envelope

promigence pricing

the price list, live (yours with a key)

--new-account
what a new account gets
--json
force the JSON envelope

promigence credits

your free-credit offer: state, credit, expiry, campaign

--json
force the JSON envelope

promigence credits claim

open the claim page (accept the terms in the browser); prints its URL

--no-open
print the URL, open nothing
--json
force the JSON envelope

promigence billing portal

manage the card on file and past invoices: prints a portal URL

--json
force the JSON envelope

Snapshots

Build a verified environment once. Everything after this is a fork of it.

promigence snapshot create

build + verify a snapshot (--image | --dockerfile | --devcontainer)

--repo R
owner/name (connected GitHub) or a git URL
--ref R
with owner/name: branch|tag|sha
--commit SHA
40-char sha, never a branch
--image REF
a tag (we pin it) or REF@sha256:D
--dockerfile PATH
a Dockerfile we build
--context DIR|URL@SHA
default: the Dockerfile's dir
--devcontainer PATH
a devcontainer.json (default: the one here)
--no-devcontainer
ignore the repo's devcontainer.json
--dir PATH
upload the files git tracks there
--from SNAP
owner/name|--dir: start from (base)
--track
owner/name: rebuild on every push
--setup CMD
setup step (ordered)
--verify CMD
must exit 0 or nothing is stored
--start CMD
background process kept running
--tier xsmall|small|medium|large|xlarge|2xlarge
build and fork size
--alias N
unique per org
--grade CMD
score the work in a clean env
--fresh
no 10-min replay (identical inputs still reuse their snapshot)
--wait
bounded by --wait-timeout (default 100s)
--wait-timeout DUR
bound (100s); expiry = exit 11, nothing killed
--idempotency-key K
a key you pick (24 h)
--json
force the JSON envelope

promigence snapshot status <build_id>

poll a build by build_id

--wait
bounded by --wait-timeout (default 100s)
--wait-timeout DUR
bound (100s); expiry = exit 11, nothing killed
--log N
print the last N lines of the build log
--json
force the JSON envelope

promigence snapshot list

list snapshots in your org

--json
force the JSON envelope

promigence snapshot inspect <hash>

show a snapshot manifest

--json
force the JSON envelope

promigence snapshot verify <hash>

re-verify a snapshot in a fork

--json
force the JSON envelope

promigence snapshot export <hash>

write a portable .promigence bundle (commit it, cite it, mail it)

--out FILE
default <alias>.promigence; - or a pipe writes stdout
--no-layers
citation form: identity + provenance + verification, no chunk table
--layers
keep the chunk table however large (default: drop it above 100 kB)
--json
force the JSON envelope

promigence image resolve REF

resolve REF (python:3.12) to REF@sha256:… without a local container runtime

--registry-secret NAME
stored secret holding user:password for a private registry
--json
force the JSON envelope

promigence github connect

install the GitHub App (browser); waits for it

--no-open
print the link, open nothing
--no-wait
print the link and return
--wait-timeout DUR
for the install (10m); expiry = exit 11
--json
force the JSON envelope

promigence github status

connected accounts, pending installs, tracked branches

--json
force the JSON envelope

promigence github disconnect <installation_id|account>

stop building from a GitHub account

--json
force the JSON envelope

promigence github untrack <track_id|alias>

stop rebuilding on push (the snapshot stays)

--json
force the JSON envelope

promigence repos

repos your GitHub connection reads (for --repo)

--page N
page (100 a page)
--json
force the JSON envelope

promigence snapshot delete <hash|alias>

remove one of your snapshots (refused while a fork of it is alive)

--json
force the JSON envelope

promigence snapshot builds

your builds, newest first (a rejected build keeps its reason)

--limit N
how many (default 20)
--state S
only this state, e.g. running | rejected
--cursor C
the next_cursor of an earlier page
--json
force the JSON envelope

promigence snapshot alias <hash> [NAME]

name a snapshot, or clear its name (unique per org)

--clear
remove the alias instead
--json
force the JSON envelope

Runs

Quote, cap, fork N copies, execute, and read which copies were valid.

promigence run -- CMD

fork N, exec CMD in each, print the validity report

--snapshot H
id | alias[@commit7] | ./env.promigence (default promigence/base)
--image REF
not with --snapshot: a tag or REF@sha256:D
--count Nrequired
sandboxes; each has PROMIGENCE_INDEX (0..N-1) and PROMIGENCE_SEED
--timeout DUR
sandbox timeout (15m)
--cap USDrequired
spend cap; refused above it (exit 5)
--allow-partial
start what the cap allows; the rest not_started
--secret NAME
stored secret as an env var
--verify-each
verify forks before hand-over
--network none|egress
default egress
--allow HOST
outbound allow-list
--optimize-for start|compute
default start
--keep-delta
keep the writable delta
--label K=V
run label
--wait-timeout DUR
bound (100s); expiry = exit 11, nothing killed
--grade CMD
score the work in a clean env
--holdout CMD
second test set; gap reported
--grade-score M
exit|last_line_json|tap (exit); JSON: {"score":0.8,"pass":true}
--grade-timeout DUR
per grader (10m)
--grade-output
keep last 16 KiB
--fail-on task|env|none
what exits non-zero (task)
--keep
keep sandboxes after CMD
--stream
live output (auto on a TTY)
--no-stream
one envelope even on a TTY
--max-output BYTES
output cap (64k)
--idempotency-key K
a key you pick (24 h)
--verbose
text: fork timings and totals too

promigence run quote

price a run before launch

--snapshot H
id | alias[@commit7] | ./env.promigence (default promigence/base)
--count Nrequired
number of sandboxes
--timeout DUR
sandbox timeout (15m)
--tier T
must match the snapshot's assigned tier
--cap USD
price it against this cap; spends nothing
--json
force the JSON envelope

promigence run report ID

validity report: env vs task failures

--json
force the JSON envelope
--sandboxes all|failed
default: summary + non-completed sandboxes
--sandbox SID
one sandbox
--repro
print the repro command for --sandbox
--limit N
text rows before '… N more' (50; 0 = all). --json is never paged

promigence run status ID

poll a run

--wait
bounded by --wait-timeout (default 100s)
--wait-timeout DUR
bound (100s); expiry = exit 11, nothing killed
--json
force the JSON envelope

promigence run cancel ID

stop queued starts

--json
force the JSON envelope

promigence run kill ID

kill every sandbox of a run

--json
force the JSON envelope

promigence run replay ID

replay sandboxes (client-triggered, never automatic)

--sandbox SID
only these sandboxes
--json
force the JSON envelope

promigence run open ID

reopen a failed sandbox as a live one, at the moment it failed

--sandbox SID
which failure (default: the only one)
--cap USD
what the reopened sandbox may spend
--timeout DUR
how long it may run (default: the run's)
--json
force the JSON envelope

promigence run captures ID

what of this run is preserved, and when it expires

--delete SNAPSHOT_ID
destroy one now, before it expires
--json
force the JSON envelope

promigence run list

your runs, newest first

--limit N
how many (default 20)
--state S
only this state
--cursor C
the next_cursor of an earlier page
--json
force the JSON envelope

Sandboxes

Long-lived sandboxes you drive command by command: exec, files, pause, resume, fork.

promigence fork

fork N sandboxes from a snapshot (--count --cap)

--snapshot H
snap_<id> | alias[@commit7] | ./env.promigence (default promigence/base)
--count Nrequired
number of sandboxes
--timeout DUR
sandbox timeout (15m)
--cap USDrequired
spend cap; refused above it (exit 5)
--allow-partial
start what the cap allows; the rest not_started
--secret NAME
stored secret as an env var
--verify-each
verify forks before hand-over
--network none|egress
default egress
--allow HOST
outbound allow-list
--optimize-for start|compute
default start
--keep-delta
keep the writable delta
--label K=V
run label
--wait-timeout DUR
bound (100s); expiry = exit 11, nothing killed
--no-wait
return after POST /runs
--fresh
skip idempotent replay
--stream
live output (auto on a TTY)
--no-stream
one envelope even on a TTY
--idempotency-key K
a key you pick (24 h)
--verbose
text: fork timings and totals too
--json
force the JSON envelope

promigence exec -- CMD

run CMD in a sandbox (--sandbox SID) or a run (--run ID --all)

--sandbox SID
stdout is the child's own bytes (JSON only with --json or PROMIGENCE_OUTPUT=json); its exit code passes through; not found 127; Promigence's own failures 125
--run ID
with --all: every ready sandbox; queued reported skipped unless --wait
--all
0 if every child exits 0, else 4
--no-passthrough
return 0–12 instead of the child's code
--background
with --sandbox: start it, print its exec_id, return now
--stdin
with --background: keep stdin open for promigence exec stdin
--secret NAME
stored secret as an env var
--stream
live output (auto on a TTY)
--no-stream
one envelope even on a TTY
--max-output BYTES
per stream (64k; 32m, the most, into a pipe or file); past it the rest is cut, and text exits 12
--timeout DUR
child timeout (default 15m)
--wait
bounded by --wait-timeout (default 100s)
--wait-timeout DUR
bound (100s); expiry = exit 11, nothing killed
--idempotency-key K
a key you pick (24 h)

promigence exec output EXEC_ID

an exec's output by id (background x_…: --follow)

--range A-B
byte range, 0-based and B inclusive; A- runs to the end
--sandbox SID
resolve the exec inside this sandbox (required for x_…)
--run ID
resolve the exec inside this run
--stderr
the child's stderr instead of its stdout
--follow
background exec: stream until it exits, pass its code through
--json
force the JSON envelope

promigence exec ps

list a sandbox's background execs

--sandbox SIDrequired
the sandbox
--json
force the JSON envelope

promigence exec stdin EXEC_ID

write to a background exec's stdin (needs exec --background --stdin)

--sandbox SIDrequired
the sandbox it runs in
--data TEXT
write this (default: read stdin to EOF)
--file P
write this local file's bytes
--eof
close stdin after writing (implied when reading a pipe)
--no-eof
keep it open after piped input
--json
force the JSON envelope

promigence exec kill EXEC_ID

signal a background exec (default SIGKILL)

--sandbox SIDrequired
the sandbox it runs in
--signal SIG
TERM | INT | HUP | KILL | a number
--forget
then drop its handle and buffered output
--json
force the JSON envelope

promigence files put SRC DST

copy a local file into a sandbox (--recursive: a directory)

--sandbox SIDrequired
target sandbox
--recursive
SRC is a local directory; DST is a directory in the sandbox
--json
force the JSON envelope

promigence files get SRC DST

copy a file out of a sandbox (--recursive: a directory)

--sandbox SIDrequired
source sandbox
--recursive
SRC is a directory in the sandbox; DST a local directory
--exclude GLOB
with --recursive: leave these out, e.g. .git
--keep-links
with --recursive: keep links leaving DST
--json
force the JSON envelope

promigence files ls [PATH]

list a directory in a sandbox (lstat per entry)

--sandbox SIDrequired
the sandbox
--recursive
walk below PATH, not one level
--depth N
with --recursive: how many levels
--limit N
stop after N entries (truncated is reported)
--no-hidden
drop dotfiles (they are listed by default)
--json
force the JSON envelope

promigence files search [PATH]

find files by name glob and/or text inside them

--sandbox SIDrequired
the sandbox
--name GLOB
name glob, e.g. '*.py'
--contains TEXT
literal text to find inside matching files
--ignore-case
case-insensitive --contains
--limit N
stop after N hits (truncated is reported)
--no-hidden
skip dotfiles and dot-directories
--json
force the JSON envelope

promigence files mkdir PATH

create a directory in a sandbox

--sandbox SIDrequired
the sandbox
--parents
mkdir -p: intermediate directories, and no error if it exists
--mode OCTAL
e.g. 755
--json
force the JSON envelope

promigence files mv SRC DST

move or rename a path inside a sandbox

--sandbox SIDrequired
the sandbox
--overwrite
replace DST if it is already there
--json
force the JSON envelope

promigence files cp SRC DST

copy a path inside a sandbox (both ends are in the sandbox)

--sandbox SIDrequired
the sandbox
--recursive
a directory and everything under it
--overwrite
replace DST if it is already there
--json
force the JSON envelope

promigence files chmod PATH

change mode and/or owner of a path in a sandbox

--sandbox SIDrequired
the sandbox
--mode OCTAL
e.g. 755
--uid N
owner
--gid N
group
--recursive
the directory and everything under it
--json
force the JSON envelope

promigence agent start claude|codex|opencode

a coding agent in a new sandbox

--key-secret NAME[=VAR]
stored secret with the model key (default ANTHROPIC_API_KEY; codex: OPENAI_API_KEY)
--key-from-env VAR
store the key from this variable first (never argv)
--snapshot H
start from this snapshot (default promigence/base; the agent is installed if missing)
--image REF@sha256:D
instead of --snapshot
--repo URL
clone this public repository and start the agent in it
--prompt TEXT
work on this task headless, in the background
--attach
open the agent's terminal now
--timeout DUR
sandbox lifetime (default 1h)
--cap USD
spend cap (else PROMIGENCE_SPEND_CAP, else the org default)
--wait-timeout DUR
bound (100s); expiry = exit 11, nothing killed
--json
force the JSON envelope

promigence sandbox kill SID

kill one sandbox

--json
force the JSON envelope

promigence sandbox network SID

what this sandbox may reach, and every host it was refused

--cut
cut this sandbox's egress now; it cannot be turned back on
--json
force the JSON envelope

promigence sandbox shell SID [-- CMD]

interactive terminal (raw TTY, follows window size)

--cmd CMD
run this instead of the login shell (sh -c)
--cwd DIR
start in this directory
--env K=V
environment variable
--secret NAME[=VAR]
stored secret in the terminal's environment; NAME=VAR binds it to VAR

promigence sandbox ssh SID [-- CMD]

log in over SSH (scp, sftp and -L work too)

--config
print an ssh config block instead of logging in
--print
print the connection details instead of logging in
--key PATH
use this key pair instead of making one
--ttl S
how long the access lasts (default 3600, max 3600)
--idle S
close a session after this long with no activity
--proxy
carry one connection on stdin/stdout (used by ssh itself)
--list
the keys that have access, then exit
--revoke KEY_ID
end one key's access (and its tunnel credential), then exit
--json
force the JSON envelope

promigence port expose PORT

publish a port as a preview URL (anyone with it can reach it)

--sandbox SIDrequired
the sandbox
--json
force the JSON envelope

promigence port list

list a sandbox's preview URLs

--sandbox SIDrequired
the sandbox
--json
force the JSON envelope

promigence port revoke TOKEN|PORT

take a preview URL down (a token, or every URL for a port)

--sandbox SIDrequired
the sandbox
--json
force the JSON envelope

promigence secrets set NAME

store secret NAME (env/file/stdin, never argv)

--from-env VAR
read the value from an environment variable
--from-file P
read the value from a file
--host HOST
bind it to a host: sandboxes get a placeholder, replaced by the value only in requests sent to the address this command prints for HOST
--header NAME
with --host: the request header the key is sent in (default: the usual key headers)
--no-raw
with --host: the value itself can never be given to a sandbox
--list
list stored secret names (no values, ever)
--delete
remove NAME
--json
force the JSON envelope

promigence sandbox list

your sandboxes, newest first

--limit N
how many (default 50)
--state S
only these states, e.g. running,ready
--label K=V
only sandboxes whose run carries every label given
--cursor C
the next_cursor of an earlier page
--json
force the JSON envelope

promigence sandbox pause SID

park a sandbox: it holds no capacity and bills no seconds

--json
force the JSON envelope

promigence sandbox resume SID

bring a paused sandbox back and restart its clock

--optimize-for start|compute
default: as created
--json
force the JSON envelope

promigence sandbox snapshot SID

snapshot it without stopping it

--json
force the JSON envelope
--alias NAME
name it
--move-alias
take the alias from the snapshot that has it
--force
take it even though the sandbox was given a secret; the snapshot, and what starts from it, can then contain that value

promigence secrets list

stored secret names (never a value)

--json
force the JSON envelope

promigence secrets delete NAME

remove a stored secret

--json
force the JSON envelope

promigence sandbox info SID

one sandbox: state, tier, time left, cost so far, and its execs

--json
force the JSON envelope

promigence sandbox extend SID

give a live sandbox more time, within its run's quote and --cap (exit 5 past them)

--timeout DURrequired
the new total timeout
--json
force the JSON envelope

promigence sandbox autopause SID

pause it once it has sat idle, or read the rule it is under

--after DUR
idle this long and it pauses itself (2s or more)
--off
never pause it on idle; only its timeout ends it
--mode MODE
requests (default) | activity: also no CPU, no bytes, no open connection inside
--json
force the JSON envelope

promigence sandbox probe SID

is this still the verified environment? (its recorded paths, or --path)

--path P
check these paths instead; PATH=blake3:<hex> where the snapshot recorded none (base, --image)
--json
force the JSON envelope

promigence files rm PATH

delete a path in a sandbox

--sandbox SIDrequired
the sandbox
--recursive
a directory and everything under it
--json
force the JSON envelope

Ops

Accounts, keys, billing, organisations, connections and CI runners.

promigence bench burst

N sandboxes at once: hand-off percentiles + success rate

--snapshot Hrequired
snap_<id> | alias[@commit7] | ./env.promigence
--count Nrequired
number of sandboxes
--timeout D
per-sandbox timeout (default 120s, the public burst harness's)
--cap USD
spend cap for the burst (required unless PROMIGENCE_SPEND_CAP is set)
--keep
leave the sandboxes running (default: killed once measured)
--json
force the JSON envelope

promigence runners github

GitHub Actions jobs in sandboxes: runs-on: promigence (until Ctrl-C)

--repo OWNER/REPO
take this repository's jobs
--org ORG
or every repository's of an organization
--runner-group NAME
with --org: the runner group (Default)
--token-env VAR
variable holding a GitHub token (GH_TOKEN, then GITHUB_TOKEN)
--labels A,B
the runs-on labels (promigence); promigence-small|medium|large pick a size
--tier small|medium|large
size of a job that names none (small)
--warm N
keep N runners waiting: instant pickup, billed while idle
--max M
sandboxes at once (10)
--cap USD
most one job may cost (default: its timeout at its size)
--timeout DUR
longest job (default: your plan's longest sandbox)
--idle-timeout DUR
stop an on-demand runner no job took (90s)
--kill-on-exit
Ctrl-C cancels running jobs instead of waiting
--prepare
build the --tier runner snapshot, then exit
--yes
build a missing runner snapshot (the build price, per size) without asking
--github-api URL
GitHub Enterprise Server's API URL
--json
force the JSON envelope

promigence runners gitlab

GitLab CI jobs in sandboxes, as a runner with your tags (until Ctrl-C)

--url URL
your GitLab (https://gitlab.com)
--token-env VAR
variable holding the runner authentication token (GITLAB_RUNNER_TOKEN)
--executor docker|shell
jobs in containers (docker) or in the sandbox
--default-image REF
docker: image of a job with no image: (ubuntu:24.04)
--pool N
runners kept up, billed while idle (1)
--api-token-env VAR
read_api token: start runners only for pending jobs
--max M
sandboxes at once (10)
--tier small|medium|large
runner size (small)
--cap USD
most one job may cost (default: its timeout at its size)
--timeout DUR
longest job (default: your plan's longest sandbox)
--idle-timeout DUR
with --api-token-env: a runner no job took exits (90s)
--kill-on-exit
Ctrl-C cancels running jobs instead of waiting
--prepare
build the --tier runner snapshot, then exit
--yes
build a missing runner snapshot (the build price) without asking
--json
force the JSON envelope

For agents

promigence agent-guide prints a compact operating guide sized for an agent’s context. --install writes it into AGENTS.md, CLAUDE.md, .claude/skills or .cursor/rules. Error codes in full

Join the waitlist

Promigence is in private beta. Leave your work email and we will send an invite as places open.