New `crates/maestro-e2e` exercises the full headless stack — registry,
two daemons, real HTTP+WS — as actual subprocesses.
Harness pieces:
- `Registry::spawn` and `Daemon::spawn` launch the real built binaries
with `env_clear()` plus an isolated `$HOME`, `XDG_CONFIG_HOME`,
`XDG_STATE_HOME`, and (for daemons) `TMUX_TMPDIR`. Drop guards kill
the child and clean the temp dirs.
- `Daemon::stop` + `Daemon::restart` swap the process without losing
the state dirs, so the recovery test exercises a real tmux
re-adoption.
- A `build::workspace_target_bin` helper re-invokes cargo from the
test process to build `maestrod` / `maestro-registry` on demand
(cargo only ships libs as path-dep of e2e by default).
- `TestClient` wraps reqwest + tokio-tungstenite for the public
HTTP+WS surface — list/spawn/kill/connect-info/attach + events WS.
Scenarios covered (`tests/e2e.rs`):
- list sessions from two daemons through one registry
- multi-attach: two WS clients see the same PTY output
- worktree with `cleanup_on_kill: true` is removed after kill
- daemon restart: catalog drops then repopulates from `recover()`
- concurrent spawns all get distinct ids
All five pass in ~0.7s in parallel; cleanup confirmed (no leftover
processes or temp dirs).