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 keychainto 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 (
mainskips 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§
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_envsucceeded: 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:
--wavedataif given (the same precedenceConfig::from_env_and_argsapplies), elseresolved. - frontend_
dir - The directory
--frontend-dirnamed, when headless and given. - is_
extra_ allowed_ origin - Is
originone--allowed-originnamed? 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
Originis: 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
mainto 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 (
--headlessorAGENTMUX_HEADLESS=1)? Never for a subcommand such asmigrate: it needs none of the headless setup, and its lock would refuse amigrate --verifyrun 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-portgave. 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.