Skip to main content
The standalone vers binary talks directly to the HTTPS control plane. It does not maintain a local project, HEAD, checkout, alias database, or implicit target. Anonymous command telemetry is a separate, optional product signal; use an environment opt-out when an invocation must leave no telemetry state. COMPUTER accepts a full computer UUID, its exact remote name, or an unambiguous UUID prefix of at least eight characters. The standalone binary and ssh vers.sh gateway have different root command sets. This page describes only the locally installed binary. The gateway has one command-output channel and no separate stderr recovery stream. Its mutation grammar therefore requires the caller to supply recovery identity up front: create and delete require --idempotency-key UUID, and commit requires --commit-id UUID. Reuse the same UUID with the exact same arguments after an uncertain result. Gateway account-key revocation also requires explicit confirmation: ssh-key revoke FINGERPRINT --yes.

SSH gateway and shell access

The SSH gateway is a separate command surface. Connect without a command for registration or an interactive command shell:
An unrecognized SSH key intentionally enters registration. The gateway asks for an email address and waits for browser verification; after registration, the same command opens the interactive shell. A registered key can also run a one-shot gateway command:
ssh vers.sh ssh COMPUTER opens an interactive SSH session to that computer. The gateway supports help, whoami, list, get, create, delete, commit, resize, write, ssh, ssh-key, env, org, and interactive exit. It does not expose standalone-only local image handling, run, durable operation inspection, retained logs, cat, or telemetry preferences. Gateway mutations require caller-owned IDs because the one-channel SSH output contract cannot print an automatically minted recovery handle separately:

Local help

These commands do not read control-plane configuration or contact the control plane:
Add --json to vers help when a program needs structured help metadata. Use this explicit help command for subcommands; vers COMMAND --help is not accepted by the standalone parser. Root help and version are not captured by telemetry. Targeted vers help commands are ordinary parsed commands and may emit the documented anonymous telemetry event. Unknown commands, misspelled options, missing confirmation flags, and invalid values are usage errors.

Authentication and endpoint

Configuration precedence is:
  1. VERS_API_KEY and VERS_ORCHESTRATOR_URL
  2. ~/.versrc
  3. the default endpoint, https://api.vers.sh
~/.versrc is JSON:
The API key is required for control-plane commands. Local help, version, upgrade, and telemetry preference commands do not require it. There is no login, logout, signup, or command-line API-key option. A custom control-plane URL must use HTTPS; HTTP is accepted only for localhost or a numeric loopback development endpoint. It must be a bare origin: credentials, a non-root path, query parameters, and fragments are rejected.

Anonymous telemetry

Anonymous CLI telemetry is enabled by default and sent directly to PostHog on a best-effort basis. It records cli_command_invoked for a parsed command and cli_command_failed for a nonzero completed result. Properties are limited to:
  • a random installation ID;
  • the typed command name, never its arguments;
  • CLI version and operating system/version and architecture;
  • failure exit status and elapsed duration.
Person profiles and GeoIP enrichment are disabled. The CLI never sends paths, command output, environment values, API credentials, or error messages. Telemetry delivery cannot change command output or exit status. Root help, version, parse failures, and telemetry-management commands are not captured. The persistent preference and random ID live in ~/.vers/telemetry.json. Inspect or change them locally:
disable removes the installation ID. For an environment-only opt-out that does not create telemetry state, set either variable:

Updating

vers upgrade checks the stable latest.json release manifest, selects the exact binary for the current operating system and architecture, and installs it beside the running executable. --check-only reports the current and latest stable versions without changing the binary. There are no automatic or background update checks. Before replacement, the updater enforces the manifest’s byte count and SHA-256 digest, runs the staged binary’s --version, and then atomically renames it over the current executable. The executable’s directory must be writable. The checksum detects corruption relative to the HTTPS manifest; it is not an independent signature or publisher-authentication mechanism.

Computers

Structured computer commands support --json unless noted otherwise.

create

Defaults are 2 vCPUs, 4096 MiB memory, and a 120-second wait. --disk is in GiB unless --mib is present. The image must first be published with vers image import; ordinary/default legacy images cannot satisfy the durable creation contract. Use run to acquire and start an OCI workload in one command; create is the lower-level detached-computer command for an existing immutable image. --no-wait returns the admitted pending outcome with status 4 rather than claiming the computer is ready. The create operation UUID is written and flushed to stderr before the first control-plane request, including with --json, so an interrupted client keeps the recovery handle without contaminating stdout.

delete

The CLI writes and flushes a durable operation identity to stderr before deleting the computer. COMPUTER_ID must be an immutable UUID obtained from vers get COMPUTER or vers list --json; names are intentionally rejected so a lost-response retry cannot be redirected after the original computer disappears or a name is reused. If the result is still pending, human output also includes the exact retry command. Reuse that identity; do not mint a new one for the same retry.

commit and resize

The CLI chooses a commit ID before sending the request and flushes it to stderr before that effect. COMPUTER_ID must be an immutable UUID obtained from vers get COMPUTER or vers list --json; names are rejected so retries cannot follow a later name binding. After an ambiguous response, rerun the exact same command with the same --commit-id; changing the computer ID, name, description, or wait policy conflicts with that identity instead of creating a different snapshot. commit creates and returns a snapshot identity, but this CLI does not yet provide restore, fork, or create-from-commit. A successful commit is therefore not an available rollback workflow in the shipped command surface. Keep the returned ID, but do not automate around an implied restore operation. Disk sizes default to GiB. Resizing only grows the root disk and requires the immutable computer UUID so a reused name cannot redirect a retry.

Workloads

run

Public OCI references are the default. --local exports the image selected by Docker, OrbStack, or Podman on the client machine. An image UUID returned by vers image import is also accepted. run chooses the computer-create identity before any image effect and derives the image-import and local-upload identities from it. It writes and flushes the create and image-import identities to stderr before image resolution, export, or upload begins. If preparation or startup is uncertain, rerun the exact same invocation with the printed --idempotency-key. Changing verified image content, the public reference or source mode, the image name, or the computer request conflicts instead of creating a second interpretation of that identity. Supplying an existing image UUID performs only a catalog read before computer creation. Use -- before a workload command, especially when it has options:
Foreground mode passes workload stdout to local stdout, workload stderr to local stderr, and returns the workload’s exit status. It does not support --json, stdin forwarding, or signal forwarding. Ctrl-C cancels local CLI work, kills and reaps any container-engine process group, waits for archive verification to stop, and exits 130. It does not signal or delete the remote computer: foreground run detaches, and server-owned --rm cleanup continues.

Logs

logs reads retained command-execution entries. workload-logs reads the primary OCI workload. With both --follow and --json, each streamed event is one newline-delimited JSON value.

Files and SSH material

Human cat output is the file’s bytes. Its JSON form contains base64. write reads piped stdin when --content is absent and accepts at most 16 MiB. It refuses to read implicitly from a terminal, so an interactive invocation must pass --content. File modes are octal (0644, 755, or 0o600) and may not exceed 7777. write requires the immutable computer UUID; cat continues to accept any COMPUTER reference. ssh-key returns private connection material for one computer. Treat its stdout as a secret. Account SSH-key management is a gateway capability and is not part of the standalone parser.

Environment variables

These account-level values are applied to future computers:
Keys must be shell identifiers: a letter or underscore followed by letters, digits, or underscores. A mutation accepts at most 100 pairs; keys are limited to 256 UTF-8 bytes and values to 8192 UTF-8 bytes. An account retains at most 256 variables. replace replaces the entire set. Deletion requires --yes.
Human env list output includes values. Treat it as secret-bearing output and avoid copying it into logs.

Images

Without --local, SOURCE is a public registry reference. With --local, the CLI uses the selected local engine and keeps private-registry credentials on the client. The CLI writes and flushes the import operation ID to stderr before resolution or local engine work. Vers runs Linux/AMD64 images. Public multi-platform references select that variant; a local source must export it. On another host architecture, pull or build with --platform linux/amd64 before retrying. A local exported archive may be at most 5,000,000,000 bytes and contain at most 17 GiB of total uncompressed layer data. Imports are durable after admission. If a wait deadline expires after the CLI has received a validated pending snapshot, it renders that snapshot on stdout and returns status 4. A deadline can instead expire during preparation, the initial operation read, or admission before any snapshot exists; those paths do not promise recovery output on stdout. Resume admitted work with image status or operation wait. --idempotency-key recovers an uncertain import admission. Retry the exact same invocation with the same key. For a local source, Vers always inspects, exports, verifies, and hashes the current archive again before resending the durable request. The key is bound to the public source reference or local verified content, optional name, image identity, archive size, digest, and format; changed semantic input fails with a conflict instead of being mistaken for the original import. Local source spelling and the engine that produced byte-identical verified content are acquisition details, not different remote effects. Transient admission failures and a reservation that is too close to expiry are retried with the same identities inside the command’s one timeout budget. Local archive reads and seeks observe that deadline and Ctrl-C cooperatively before later hashing or upload can begin. Image JSON is a CLI-owned contract rather than a pass-through of control-plane responses. Import and inspect return one image object; list returns one bounded array page of those objects. --limit defaults to 50 and cannot exceed 100; --offset selects the next page without making the CLI aggregate an unbounded catalog in memory. A pending import or status wait returns the same recovery shape as a non-waiting status: import_id, status, cursor, stage, image_id, failure, and its three timestamps. Delete returns { "deleted": false, "image_id": "<UUID>" } on an already-absent replay and the same shape with deleted set to true on the first deletion. Image deletion accepts only the immutable UUID printed by image list or image inspect; names are intentionally rejected because they can be reused. Repeating deletion of the same UUID succeeds and reports that the image is already absent. An image referenced by a live computer or lifecycle resource still fails with a conflict.

Durable operations

get reads one snapshot. wait follows the durable event stream and resumes across reconnects until the operation becomes terminal or the deadline expires. The default wait deadline is 1800 seconds. After wait obtains a validated snapshot, a later timeout renders the last pending snapshot on stdout before returning status 4. If the initial read itself reaches the deadline, no snapshot is available to render.

JSON and output channels

--json exists only on commands that advertise it above. Structured commands render one CLI-owned result in either human or JSON form. Progress and recovery diagnostics go to stderr, leaving stdout available for results and pipelines. Foreground run is different: it preserves the workload’s stdout, stderr, and status instead of wrapping them in JSON.

Exit status

Foreground run may return any workload exit status. If a workload terminates by signal, it returns 128 + signal. Anonymous CLI telemetry follows the documented default-on, explicit-opt-out contract above.