From f17aae3bd289064c0813f68e19723b7d7a5ae933 Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Wed, 8 Apr 2026 19:43:40 -0700 Subject: [PATCH] feat: add dev command for hot-reload (uvicorn --reload + Vite HMR) - manage.sh: dev command starts uvicorn --reload on :8503 and Vite dev server (auto-port from 5173); kills API on EXIT/INT/TERM trap - manage.sh: ENV_UI defaults to 'cf' env (overridable via AVOCET_ENV) - vite.config.ts: add server.proxy to forward /api to :8503 so Vite dev server can reach the backend without CORS issues --- manage.sh | 44 +++++++++++++++++++++++++++++++++++++++++++- web/vite.config.ts | 5 +++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/manage.sh b/manage.sh index 734a188..847e8c3 100755 --- a/manage.sh +++ b/manage.sh @@ -19,7 +19,7 @@ LOG_FILE="${LOG_DIR}/label_tool.log" DEFAULT_PORT=8503 CONDA_BASE="${CONDA_BASE:-/devl/miniconda3}" -ENV_UI="job-seeker" +ENV_UI="${AVOCET_ENV:-cf}" ENV_BM="job-seeker-classifiers" PYTHON_BM="${CONDA_BASE}/envs/${ENV_BM}/bin/python" PYTHON_UI="${CONDA_BASE}/envs/${ENV_UI}/bin/python" @@ -91,6 +91,7 @@ usage() { echo -e " ${GREEN}compare [args]${NC} Shortcut: --compare [args]" echo "" echo " Dev:" + echo -e " ${GREEN}dev${NC} Hot-reload: uvicorn --reload (:8503) + Vite HMR (:5173)" echo -e " ${GREEN}test${NC} Run pytest suite" echo "" echo " Port defaults to ${DEFAULT_PORT}; auto-increments if occupied." @@ -165,6 +166,47 @@ case "$CMD" in exec bash "$0" start ;; + dev) + API_PORT=8503 + VITE_PORT=5173 + DEV_API_PID_FILE=".avocet-dev-api.pid" + mkdir -p "$LOG_DIR" + DEV_API_LOG="${LOG_DIR}/dev-api.log" + + if [[ -f "$DEV_API_PID_FILE" ]] && kill -0 "$(<"$DEV_API_PID_FILE")" 2>/dev/null; then + warn "Dev API already running (PID $(<"$DEV_API_PID_FILE"))" + else + info "Starting uvicorn with --reload on port ${API_PORT}…" + nohup "$PYTHON_UI" -m uvicorn app.api:app \ + --host 0.0.0.0 --port "$API_PORT" --reload \ + >> "$DEV_API_LOG" 2>&1 & + echo $! > "$DEV_API_PID_FILE" + # Wait for API to bind + for _i in $(seq 1 20); do + sleep 0.5 + (echo "" >/dev/tcp/127.0.0.1/"$API_PORT") 2>/dev/null && break + if ! kill -0 "$(<"$DEV_API_PID_FILE")" 2>/dev/null; then + rm -f "$DEV_API_PID_FILE" + error "Dev API died during startup. Check ${DEV_API_LOG}" + fi + done + success "API (hot-reload) → http://localhost:${API_PORT}" + fi + + # Kill API on exit (Ctrl+C or Vite exits) + _cleanup_dev() { + local pid + pid=$(<"$DEV_API_PID_FILE" 2>/dev/null || true) + [[ -n "$pid" ]] && kill "$pid" 2>/dev/null && rm -f "$DEV_API_PID_FILE" + info "Dev servers stopped." + } + trap _cleanup_dev EXIT INT TERM + + info "Starting Vite HMR on port ${VITE_PORT} (proxy /api → :${API_PORT})…" + success "Frontend (HMR) → http://localhost:${VITE_PORT}" + (cd web && npm run dev -- --host 0.0.0.0 --port "$VITE_PORT") + ;; + open) URL="http://localhost:8503" info "Opening ${URL}" diff --git a/web/vite.config.ts b/web/vite.config.ts index c22afdb..db9195b 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -4,6 +4,11 @@ import UnoCSS from 'unocss/vite' export default defineConfig({ plugins: [vue(), UnoCSS()], + server: { + proxy: { + '/api': 'http://localhost:8503', + }, + }, test: { environment: 'jsdom', globals: true,