Skip to main content

Module headless

Module headless 

Source
Expand description

Headless mode: srv started directly — a container entrypoint, a server, CI — with no launcher or desktop host. docs/specs/SPEC_SRV_HEADLESS_MODE_2026_09_26.md.

Normally the launcher prepares srv’s world before spawning it: the data-path env (DataPaths::to_env_vars), a per-launch auth key, and a stdin pipe and parent process whose end means “shut down”. Headless srv does that itself:

  • resolves and exports the data-path env when it isn’t already set;
  • takes srv’s data-dir lock early (the same lock every srv takes), so no two servers — headless or launcher-started — share a set of databases;
  • takes its auth key from AGENTMUX_AUTH_KEY, --auth-key-file, or generates one and writes it to <data dir>/srv-auth-key (0600) — the key is never printed, only the file’s path;
  • keeps secrets in owner-only files under the shared dir instead of the OS keychain, which a container usually doesn’t have (--secret-store keychain to use the keychain anyway);
  • turns the cloud subscriber off: a server doesn’t connect to the AgentMux cloud relay on its own;
  • is not tied to stdin or a parent process (main skips those watchers); SIGINT/SIGTERM still shut it down.

It still binds loopback only (--web-port / --ws-port fix the ports). Reaching it from another machine is a reverse proxy’s job, not srv’s. For a client behind such a proxy, --frontend-dir serves the built frontend and --allowed-origin names the proxy’s origin for CORS and the /ws check.

Structs§

WebOptions 🔒

Enums§

Listener
Which startup listener a bind address is for.

Constants§

AUTH_KEY_FILE_NAME
File name of the generated auth key, beside the databases.

Statics§

ACTIVE 🔒
Set once prepare_env succeeded: this process is the headless server.
PORTS 🔒
--web-port / --ws-port, held in-process (never in the env, so a launcher-spawned srv or an agent can’t inherit them — ReAgent P1 on #3893).
WEB 🔒
--frontend-dir / --allowed-origin, held in-process like the ports.

Functions§

active
Is this process running headless (after prepare_env)?
bind_addr_with 🔒
effective_data_dir 🔒
The directory srv will open its databases in: --wavedata if given (the same precedence Config::from_env_and_args applies), else resolved.
frontend_dir
The directory --frontend-dir named, when headless and given.
is_extra_allowed_origin
Is origin one --allowed-origin named? Always false for a srv that isn’t headless.
normalize_origin 🔒
An origin as browsers send it, via the WHATWG URL parser browsers use: http or https, a host, an optional port — no path, user, query or fragment. Serialized the way Origin is: lowercase, IDNA hosts in punycode, canonical IPv4/IPv6, and no default port, so every spelling of one origin compares equal (Codex P2s on #3900). A trailing / is fine.
origin_in 🔒
prepare_env
Prepare the environment the launcher would normally provide. Runs before logging is initialized, so problems are returned for main to print. Returns the path the auth key was written to, when it generated one.
read_key_file 🔒
Read a key from a file the operator provided; surrounding whitespace is ignored.
requested
Is this the headless server starting (--headless or AGENTMUX_HEADLESS=1)? Never for a subcommand such as migrate: it needs none of the headless setup, and its lock would refuse a migrate --verify run beside a running headless server (ReAgent P1 on #3893).
requested_from 🔒
startup_bind_addr
The address a startup listener binds: STARTUP_BIND_ADDR (loopback, OS-chosen port) — or, headless only, the same loopback host with the port --web-port / --ws-port gave. A non-headless srv always gets the default.
web_options 🔒
write_generated_key 🔒
Generate a fresh key and write it to <dir>/srv-auth-key, readable by the owner only. A new key every start, like a launcher-spawned srv.