Skip to main content
Commands are rows in agent_commands. They represent every instruction the UI gives to a gateway — provisioning agents, approving pairings, connecting providers, restarting services, and more.

State machine

pending  →  leased  →  running  →  done
                    ↘          ↘  failed
1

UI inserts a command

A server action writes a row to agent_commands with status = 'pending'.
2

Runner leases the command

The runner daemon picks it up via Realtime subscription or polling, then calls lease_command(p_gateway_slug) to atomically claim it.
3

Runner executes

The runner maps the command action to a shell operation (e.g. add-agent.sh for provision) and runs it.
4

Runner reports results

On completion, the runner writes stdout, stderr, exit_code, and final status (done or failed) back to the row.

RPC lifecycle calls

The runner uses four RPCs to manage command state:
RPCCalled when
lease_command(p_gateway_slug, p_lease_seconds)Runner atomically claims a pending command. Returns the command row or nothing. Lease duration = COMMAND_TIMEOUT + 60 seconds.
start_command(p_command_id)Runner marks the command running just before executing it.
complete_command(p_command_id, p_exit_code, p_stdout, p_stderr)Command exited 0.
fail_command(p_command_id, p_exit_code, p_stdout, p_stderr, p_error)Command failed (non-zero exit, timeout, or validation error).
Connection actions (auth_*) call start_command and complete_command/fail_command themselves — they don’t go through the standard shell-command path.

Durability

Commands are never deleted after completion. They persist as a full history of every operation — viewable from Settings → System → Commands.
If a command is stuck in leased or running for more than 5 minutes, the runner likely crashed or lost its lease. Check docker compose logs runner for details.
See Command actions for the full list of supported actions and their payload schemas.