The vai command
vai is one Go binary for macOS, Linux and Windows, installed with a second name, vaicoa, for scripts and for machines where vai is taken. vai help lists the commands; vai help twin the commands that start with twin.
usage: vai [--hub NAME] [--agent INTEGRATION] [--output text|json] [--passphrase-file FILE] <command> [arguments]Commands
Section titled “Commands”The portal and the hub
Section titled “The portal and the hub”| command | what it does |
|---|---|
vai login / logout / whoami | sign in at the portal in the browser for your licence; the token goes to the OS credential store |
vai up NAME [--location nbg1] [--server-type T] [--token-file F | --hcloud-context C] [--twins-…] [--plan] [--yes] [--abort] | create a hub in your project, pair this device as its owner, activate the licence (resumable) |
vai down NAME [--plan] [--confirm NAME] | delete a hub and everything of it in the project (refused while it manages a server) |
vai upgrade [NAME] --dist DIR [--plan] | install another hub release on the hub’s server, data and pairings kept |
vai status [NAME] | the hub: its licence, servers, twins, open approvals and releases |
vai open [PATH] | the hub’s portal in the browser, through a local proxy while vai runs |
vai hub list / hub current / hub use NAME | the hubs on this machine, which one a command talks to and why, the default |
vai licence | the licence as the hub and the portal see it |
Devices and agents
Section titled “Devices and agents”| command | what it does |
|---|---|
vai pair INVITE | pair this machine with a hub, with an invite (or --listener URL --code CODE) |
vai pair invite --role ROLE [--name NAME] | an invite for another device (owner): one string, valid 10 minutes |
vai devices / devices revoke ID|NAME [--confirm NAME] | the hub’s devices; revoke one (owner) |
vai agent register INTEGRATION | register this device’s agent key for an integration (a person, once) |
vai agent revoke INTEGRATION [--device ID] | revoke an agent key |
vai approvals [--all] | what agents and capped devices asked a person to approve |
vai approve ID [--confirm NAME] / reject ID | approve (a presence device only) or reject one |
Hosts and environments
Section titled “Hosts and environments”| command | what it does |
|---|---|
vai host create NAME [--type cpx22] [--env production|staging] [--location L] [--release V] | a production or staging Podman host |
vai host list / host delete NAME [--confirm NAME] | the hosts; delete one and its server (a device below presence asks for an approval) |
vai open host NAME / host access NAME [--from ADDR,…] / host access list / host access revoke | reach a staging host that is not public, as for twins |
vai host public NAME [on|off] | whether a staging host is public (80/443 from anywhere, its own TLS) |
vai host reseed NAME [--copy-from PRODUCTION] | reseed a staging host’s data, or fill it with a copy of production |
vai env copy PRODUCTION / env copy allow PRODUCTION --reason R [--mask required|waived] / env copy forbid PRODUCTION | whether twins may hold a copy of a production host’s data (allowing: owner, presence device) |
vai release list / release promote VERSION --host NAME [--now] | the releases the hub imported; promote one to a host |
| command | what it does |
|---|---|
vai twin create --production HOST --task TASK [--branch B] [--ttl H] [--data seed|copy|empty] | a twin of a production or staging host |
vai twin list [--all] / twin show TWIN / twin evidence TWIN | the twins; one twin’s state, data and web access; what the hub knows of it, with its digest |
vai twin extend TWIN --hours H | extend a twin once |
vai twin reset TWIN / twin reseed TWIN | back to its checkpoint; run its seed again |
vai twin delete TWIN [--confirm TASK] | delete a twin and its server |
vai open twin TWIN [--ttl 1h] | a twin’s page in the browser, through a grant from this device’s address |
vai twin access TWIN [--from ADDR,… | --any] [--ttl 1h] / twin access list / twin access revoke | web access links for named addresses |
vai twin settings [--type T --location L] [--token-file F | --hcloud-context C] | the twins’ Hetzner project (owner) |
vai dns status / dns setup --zone ZONE [--base NAME] / dns verify | twin names from a zone in Hetzner’s Cloud DNS (owner) |
Scripts
Section titled “Scripts”| command | what it does |
|---|---|
vai api METHOD PATH [JSON|-] | one signed request to the hub’s admin API; a path without /api/ gets /api/v1 in front |
vai version | the version |
Which hub
Section titled “Which hub”A machine can know several hubs, like kubectl’s contexts. A command talks to one, chosen in this order: --hub NAME, then VAI_HUB, then the default (vai hub use NAME), then the only hub there is. Every command that changes something names the hub first, on stderr (hub: acme).
Agent mode
Section titled “Agent mode”A coding agent runs vai --agent INTEGRATION …, or has VAI_AGENT=INTEGRATION in its environment. Its requests are signed with the device’s agent key for that integration and held to the agent’s ceiling; the first use registers the key, which asks a person once. With VAI_AGENT set, what only a person may sign is refused before anything is signed: vai open, vai approve, pairing, vai agent register and revoke. See agents and approvals.
Destructive commands take --confirm NAME and never --yes, so an agent can call them without a terminal; the hub still decides.
One link per device
Section titled “One link per device”A device reaches its hub through a WireGuard tunnel inside the vai process. While a long-lived vai runs (vai open, vai open twin), it shares its tunnel with the other vai runs of the same user on a local socket that only that user can use; every request is still signed by its own key, end to end. There is no daemon: nothing listens unless a long-lived vai runs. On Windows each vai opens its own tunnel.
Environment variables
Section titled “Environment variables”| variable | effect |
|---|---|
VAI_HUB | the hub a command talks to, after --hub |
VAI_AGENT | agent mode for that integration, as --agent; vai then never signs with the person’s key |
VAI_AGENT_SESSION | the agent’s session in the audit; default: one per vai run |
VAI_HOME | one directory for everything of vai, instead of the system’s default places |
VAI_NO_BROWSER | set: vai login, vai open and vai open twin print the link instead of opening a browser |
VAI_LINK_SHARE | off: this run neither uses nor shares another run’s tunnel |
VAI_PASSPHRASE_FILE, VAI_PASSPHRASE | the passphrase of a key file, from a file or the environment (level passphrase-stored) |
Before the rename these were PBX_*. The old names are not read; vai moves its old directories once.
Output and exit codes
Section titled “Output and exit codes”Plain lines for people; --output json for scripts; --progress json on long commands.
| code | meaning |
|---|---|
| 0 | ok |
| 1 | failed |
| 2 | usage |
| 3 | the hub answered with a status other than 2xx |
| 4 | refused by policy: the waitlist, a ceiling, the protection level |
| 5 | waiting for a person’s approval (202); the approval’s id is printed |