ci / rust (push) Successful in 1m27s
`web/vite.config.ts` was hard-coded to proxy `/api` at `http://127.0.0.1:8080`, so pointing the dev UI at a remote registry meant hand-editing the file. Read `MAESTRO_REGISTRY` from the environment via `loadEnv` instead, with the local default preserved. Accept either the HTTP base URL (`https://…`) or the daemon-facing URL (`wss://…/daemon`) — the latter is rewritten to `https://…` and the `/daemon` suffix stripped, since the proxy needs the HTTP origin. Flips `changeOrigin: true` for HTTPS upstreams so the proxied Host matches the cert. Documented under `web/README.md` § Dev.
64 lines
2.1 KiB
Markdown
64 lines
2.1 KiB
Markdown
# maestro-web
|
|
|
|
Browser UI for Maestro. Connects to the registry HTTP/WS API for the catalog
|
|
and to individual daemons (via direct WebSocket) for terminal I/O.
|
|
|
|
## Framework choice: vanilla TypeScript
|
|
|
|
No frontend framework. The UI is small enough that the cost of pulling in
|
|
Preact / Solid / Leptos doesn't pay back. xterm.js does all the heavy
|
|
rendering; everything else is a session tree and a spawn form, both trivial
|
|
in plain DOM.
|
|
|
|
This decision is non-architectural — swap in a framework later without
|
|
touching the registry or daemon if needed.
|
|
|
|
## Layout
|
|
|
|
```
|
|
src/
|
|
main.ts # entry point, hash-route dispatch
|
|
api.ts # registry HTTP API client
|
|
events.ts # `/api/events` WebSocket subscriber
|
|
catalog.ts # session tree view (groups by metadata.label)
|
|
attach.ts # xterm.js + daemon WS attach view
|
|
spawn.ts # spawn-session modal
|
|
types.ts # mirror of `maestro-protocol` JSON shapes
|
|
styles.css # mobile-first base styles
|
|
```
|
|
|
|
Routing is hash-based:
|
|
- `#/` → catalog
|
|
- `#/attach/<session-id>` → terminal
|
|
|
|
This keeps the registry's static handler dumb (no SPA fallback needed).
|
|
Concurrent attaches: open the same `#/attach/<id>` URL in another tab.
|
|
|
|
## Dev
|
|
|
|
```sh
|
|
pnpm install
|
|
pnpm dev # http://localhost:5173, proxies /api → http://127.0.0.1:8080
|
|
pnpm build # → dist/, embedded into the registry binary at cargo build time
|
|
```
|
|
|
|
The Vite dev server proxies `/api` and the events WebSocket to a
|
|
`maestro-registry`. Default is `http://127.0.0.1:8080`; point it elsewhere by
|
|
exporting `MAESTRO_REGISTRY` before `pnpm dev`:
|
|
|
|
```sh
|
|
MAESTRO_REGISTRY=https://maestro-registry.example.com pnpm dev
|
|
# Daemon-facing URL also works — `wss://...` is rewritten to `https://...`
|
|
# and a trailing `/daemon` is stripped.
|
|
MAESTRO_REGISTRY=wss://maestro-registry.example.com/daemon pnpm dev
|
|
```
|
|
|
|
Direct daemon WS connections (for attach) bypass the proxy and use the URL
|
|
returned by `GET /api/sessions/:id/connect-info`.
|
|
|
|
## Production
|
|
|
|
`pnpm build` writes the bundle to `web/dist/`. The Rust registry crate
|
|
embeds that directory via `rust-embed` at compile time and serves it from
|
|
`/`. See `crates/maestro-registry/src/web_assets.rs`.
|