Closes NAP-216. Thin client for the registry HTTP API + per-session daemon WebSocket. Becomes the headless test harness for NAP-217 and unblocks the demo-by-script path before the web client lands (NAP-218). Crate layout (`crates/maestro-cli/`): - `cli.rs` — clap-derive parser. Commands: `list`, `spawn`, `attach`, `kill`, `set-registry`. Global `--registry-url` (env `MAESTRO_REGISTRY_URL`), `--config`, repeatable `-v`. - `config.rs` — `CliConfig` persisted at `~/.config/maestro/cli.toml`, storing the default registry URL + the session cookie issued by the registry's cookie middleware. - `http.rs` — `RegistryClient` wrapping `reqwest`. Attaches the persisted cookie, captures `Set-Cookie` responses (first-contact bootstrap and rotation), atomically writes the new value back to the config file. - `sessions.rs` — `list/spawn/kill` + connect-info fetch. `list` prints a per-daemon grouped table; `--json` for scripting. - `attach.rs` — raw-TTY WS proxy. Termios cfmakeraw with an RAII guard for restore-on-drop, SIGWINCH → `ClientControl::Resize` text frame, configurable detach key (default Ctrl-q; accepts `^X` form), echoes `Ping`/`Pong` for keepalive symmetry with the daemon side. Workspace deps added: clap (derive+env), reqwest (rustls+cookies), nix (term+signal). Smoke-tested against the live registry at maestro-registry.n62.casa: `maestro list` issued + persisted the cookie and printed the empty catalog cleanly. 19 new unit tests (parser, config round-trip, table-printing, cookie extraction, attach URL/detach-key parsing). Full workspace `cargo test`: 97 passed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,12 +12,15 @@ publish = false
|
||||
[workspace.dependencies]
|
||||
axum = { version = "0.7", features = ["ws"] }
|
||||
chrono = { version = "0.4", default-features = false, features = ["clock", "serde"] }
|
||||
clap = { version = "4.5", features = ["derive", "env"] }
|
||||
dirs = "5"
|
||||
futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] }
|
||||
jsonwebtoken = { version = "9", default-features = false }
|
||||
libc = "0.2"
|
||||
maestro-protocol = { path = "crates/maestro-protocol" }
|
||||
nix = { version = "0.29", default-features = false, features = ["term", "signal"] }
|
||||
rand = "0.8"
|
||||
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls", "cookies"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
tempfile = "3"
|
||||
|
||||
Reference in New Issue
Block a user