This repository has been archived on 2026-10-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
maestro/crates/maestro-web/README.md
T
naps62-yoloandClaude Opus 4.7 bc3237287f feat(maestro): maestro-web standalone binary + reverse-proxy (NAP-241)
New crate crates/maestro-web/: axum server that

* embeds the web/dist SPA bundle via include_dir! (graceful placeholder when
  pnpm build hasn't run yet — keeps fresh checkouts compiling)
* reverse-proxies /api/* HTTP to a co-located daemon (default
  http://127.0.0.1:7070) via reqwest, stripping hop-by-hop headers
* reverse-proxies /api/attach/:id and /api/events WebSockets via
  tokio_tungstenite::connect_async + a tokio task pumping both directions
* reads bind_addr / daemon_url / dev_proxy_target from the new [web]
  config section; env-var overrides MAESTRO_WEB_BIND_ADDR / _DAEMON_URL /
  _DEV_PROXY_TARGET

Integration tests spin up a mock daemon + maestro-web pair on random ports
and verify HTTP forward, SPA fallback, WS echo, and 502 on unreachable
daemon.

Adds a top-level Justfile (`just web` = pnpm install + pnpm build + cargo
build), crates/maestro-web/README.md (config + trust model + dev workflow),
and a docs/INSTALL.md section on optional web UI install.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 18:23:14 +00:00

2.4 KiB

maestro-web

Standalone HTTP server that hosts the Maestro browser UI and reverse-proxies to a co-located maestrod.

browser  ──HTTP──▶  maestro-web (:8080)  ──HTTP/WS──▶  maestrod (:7070)
                         │
                         └── /          serves the embedded SPA (web/dist)
                             /api/...   proxied unmodified
                             /api/attach/:id, /api/events  proxied as WebSocket

Trust model

maestro-web does not authenticate anyone. Whoever can reach the bind address can use it. Pick the bind accordingly:

Bind Reach Use when
127.0.0.1:8080 Local users on this host Default. Same as tmux.
<wg-ip>:8080 Devices on your WireGuard mesh Phone/tablet over VPN.
<lan-ip>:8080 Devices on your trusted LAN Home / lab networks.
Public IP Don't — add real auth first.

Config

The binary reads ~/.config/maestro/config.toml. The [web] section:

[web]
bind_addr        = "127.0.0.1:8080"      # default
daemon_url       = "http://127.0.0.1:7070"  # default
# dev_proxy_target = "http://127.0.0.1:5173"  # only when developing the frontend

Env-var overrides (all optional):

  • MAESTRO_WEB_BIND_ADDR
  • MAESTRO_WEB_DAEMON_URL
  • MAESTRO_WEB_DEV_PROXY_TARGET
  • MAESTRO_CONFIG — override the unified config-file path.

Build

The SPA bundle lives in ../../web and is embedded into the binary at compile time via include_dir!. Build the frontend first:

pnpm -C web install
pnpm -C web build
cargo build -p maestro-web --release

Or, from the repo root:

just web

A fresh checkout compiles even without pnpm build (an empty web/dist exists in-tree); the binary just serves a placeholder until the bundle is built.

Run

target/release/maestro-web

Then point a browser at http://127.0.0.1:8080/.

Development workflow for the frontend

Use Vite directly so you get HMR. From web/:

pnpm dev

Vite serves on :5173 and proxies /api/* straight to maestrod at 127.0.0.1:7070 (override with MAESTRO_REGISTRY=...). You don't need to rebuild the Rust binary while iterating on the frontend.