#!/usr/bin/env bash # evOo-local — start the stack from this checkout (used by evoo-local.service). # api, worker and sandbox supervisor run as `pnpm dev` runs them. The web app runs as the Vite dev # server (EVO_WEB_MODE=dev, the default) or serves the production build with `vite preview` on the # same port (EVO_WEB_MODE=preview). `--check` validates the configuration and exits. set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" EVO_WEB_MODE="${EVO_WEB_MODE:-dev}" log() { printf '[evo-stack] %s\n' "$*" >&2; } die() { log "ERROR: $*"; exit 1; } # `vite preview` runs with NODE_ENV=production, so apps/web/vite.config.ts refuses development # secrets. Resolve the env the way that config does (process env first, then the root .env files) # and run the same guard, so a missing value fails here instead of inside a restart loop. check_preview() { [[ -f "$ROOT/apps/web/dist/index.html" ]] || die "apps/web/dist has no build; run: pnpm --filter @rakazo/web build" (cd "$ROOT/apps/web" && NODE_ENV=production "$ROOT/node_modules/.bin/tsx" --input-type=module -e ' import { loadEnv } from "vite"; import { resolveScreenProxySecret } from "../../packages/core/src/secrets-guard.ts"; const files = loadEnv("production", "../..", ""); const env = { ...process.env }; for (const key of ["RAKAZO_HOST", "SCREEN_PROXY_SECRET", "SANDBOX_SUPERVISOR_TOKEN", "BETTER_AUTH_SECRET"]) { env[key] = files[key]; } const problems = []; if (!env.RAKAZO_HOST?.trim()) problems.push("Set RAKAZO_HOST to the hostname the web app is served on."); try { resolveScreenProxySecret(env); } catch (error) { problems.push(error.message); } for (const problem of problems) console.error("[evo-stack] ERROR: " + problem); process.exitCode = problems.length > 0 ? 1 : 0; ') } start_preview() { pnpm dev '--filter=!@rakazo/web' & SERVICES_PID=$! NODE_ENV=production pnpm --filter @rakazo/web preview --strictPort & WEB_PID=$! trap 'kill "$SERVICES_PID" "$WEB_PID" 2>/dev/null || true' EXIT trap 'exit 143' TERM trap 'exit 130' INT # Polling instead of `wait -n` keeps this working on bash 3.2. while kill -0 "$SERVICES_PID" 2>/dev/null && kill -0 "$WEB_PID" 2>/dev/null; do sleep 1 done die "a service exited; stopping the stack" } main() { case "${1:-}" in "" | --check) ;; *) die "usage: start-stack.sh [--check]" ;; esac case "$EVO_WEB_MODE" in dev | preview) ;; *) die "EVO_WEB_MODE must be dev or preview (got: $EVO_WEB_MODE)" ;; esac cd "$ROOT" if [[ "$EVO_WEB_MODE" == preview ]]; then check_preview fi if [[ "${1:-}" == --check ]]; then log "ok ($EVO_WEB_MODE)" return 0 fi if [[ "$EVO_WEB_MODE" == dev ]]; then exec pnpm dev fi start_preview } main "$@"