From f0b01ae295951599de2c6872fd275c7829ffad25 Mon Sep 17 00:00:00 2001 From: naps62-yolo Date: Mon, 25 May 2026 15:35:57 +0000 Subject: [PATCH] feat(maestro): let vite dev proxy honor \$MAESTRO_REGISTRY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `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. --- web/README.md | 17 +++++++++++---- web/vite.config.ts | 53 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/web/README.md b/web/README.md index 5747cdc..8718ed8 100644 --- a/web/README.md +++ b/web/README.md @@ -42,10 +42,19 @@ 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 locally -running `maestro-registry` (default `127.0.0.1:8080`). Direct daemon WS -connections (for attach) bypass the proxy and use the URL returned by -`GET /api/sessions/:id/connect-info`. +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 diff --git a/web/vite.config.ts b/web/vite.config.ts index 3b458f4..b4fe962 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -1,20 +1,41 @@ -import { defineConfig } from "vite"; +import { defineConfig, loadEnv } from "vite"; -export default defineConfig({ - build: { - target: "es2022", - outDir: "dist", - emptyOutDir: true, - sourcemap: false, - }, - server: { - port: 5173, - proxy: { - "/api": { - target: "http://127.0.0.1:8080", - changeOrigin: false, - ws: true, +// Where the dev proxy forwards `/api/*` (and the events WS) to. Default to a +// local `maestro-registry` on 127.0.0.1:8080. Override by exporting either: +// MAESTRO_REGISTRY=https://maestro-registry.example.com (preferred) +// MAESTRO_REGISTRY=wss://maestro-registry.example.com/daemon +// The second form (the daemon-facing URL) is normalised: ws/wss → http/https +// and any trailing `/daemon` is stripped, since the proxy needs the base URL. +function resolveProxyTarget(raw: string | undefined): string { + if (!raw) return "http://127.0.0.1:8080"; + return raw + .replace(/^wss:\/\//, "https://") + .replace(/^ws:\/\//, "http://") + .replace(/\/daemon\/?$/, "") + .replace(/\/+$/, ""); +} + +export default defineConfig(({ mode }) => { + const env = loadEnv(mode, process.cwd(), ""); + const target = resolveProxyTarget(env.MAESTRO_REGISTRY); + const secure = target.startsWith("https://"); + return { + build: { + target: "es2022", + outDir: "dist", + emptyOutDir: true, + sourcemap: false, + }, + server: { + port: 5173, + proxy: { + "/api": { + target, + changeOrigin: secure, + ws: true, + secure: false, + }, }, }, - }, + }; });