Spaces:
Running on T4
Running on T4
| # OmniVoice Studio β universal launcher. | |
| # | |
| # Works on macOS, Linux, and WSL. Starts the FastAPI backend, waits for it | |
| # to become healthy, then opens the web UI in the default browser. | |
| # | |
| # Usage: | |
| # ./run.sh # normal launch | |
| # ./run.sh --no-open # skip auto-opening browser | |
| # Press Ctrl+C to shut down. | |
| set -e | |
| # ββ Output style ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| if [ -n "${NO_COLOR:-}" ]; then | |
| C_OK="" C_DIM="" C_ERR="" C_RST="" | |
| elif [ -t 1 ] || [ -n "${FORCE_COLOR:-}" ]; then | |
| _ESC="$(printf '\033')" | |
| C_OK="${_ESC}[38;5;108m" | |
| C_DIM="${_ESC}[38;5;245m" | |
| C_ERR="${_ESC}[91m" | |
| C_RST="${_ESC}[0m" | |
| else | |
| C_OK="" C_DIM="" C_ERR="" C_RST="" | |
| fi | |
| have() { command -v "$1" >/dev/null 2>&1; } | |
| # ββ Parse flags βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| NO_OPEN=false | |
| for arg in "$@"; do | |
| case "$arg" in | |
| --no-open) NO_OPEN=true ;; | |
| esac | |
| done | |
| # ββ Resolve script directory βββββββββββββββββββββββββββββββββββββββββββββββ | |
| SCRIPT_DIR="$(cd "$(dirname "$0")" 2>/dev/null && pwd)" | |
| cd "$SCRIPT_DIR" | |
| # ββ Detect platform ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| OS="linux" | |
| if [ "$(uname)" = "Darwin" ]; then | |
| OS="macos" | |
| elif grep -qi microsoft /proc/version 2>/dev/null; then | |
| OS="wsl" | |
| fi | |
| # ββ PATH: ensure common shell-installed tools are available ββββββββββββββββ | |
| export PATH="$HOME/.local/bin:$HOME/.bun/bin:$PATH" | |
| case "$OS" in | |
| macos) | |
| export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" | |
| ;; | |
| esac | |
| # ββ Sanity check βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| if [ ! -d .venv ]; then | |
| printf "${C_ERR}β No .venv/ β run ./install.sh first.${C_RST}\n" >&2 | |
| exit 1 | |
| fi | |
| # ββ Log directory (platform-aware) βββββββββββββββββββββββββββββββββββββββββ | |
| case "$OS" in | |
| macos) LOG_DIR="$HOME/Library/Application Support/OmniVoice" ;; | |
| *) LOG_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/OmniVoice" ;; | |
| esac | |
| mkdir -p "$LOG_DIR" | |
| LOG_FILE="$LOG_DIR/omnivoice-run.log" | |
| # ββ Start backend ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| PORT=3900 | |
| echo "${C_OK}βΈ${C_RST} Starting backend on port ${PORT} (log: ${C_DIM}${LOG_FILE}${C_RST})β¦" | |
| uv run uvicorn main:app --app-dir backend --host 127.0.0.1 --port "$PORT" \ | |
| >"$LOG_FILE" 2>&1 & | |
| BACKEND_PID=$! | |
| # ββ Cleanup on exit ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| cleanup() { | |
| echo "" | |
| echo "${C_DIM}βΈ Shutting down backend (pid $BACKEND_PID)β¦${C_RST}" | |
| kill "$BACKEND_PID" 2>/dev/null || true | |
| wait "$BACKEND_PID" 2>/dev/null || true | |
| } | |
| trap cleanup EXIT INT TERM | |
| # ββ Wait for backend health ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| echo "${C_DIM}βΈ Waiting for backendβ¦${C_RST}" | |
| _deadline=60 | |
| _elapsed=0 | |
| while [ "$_elapsed" -lt "$_deadline" ]; do | |
| # Try curl first, fall back to wget | |
| if have curl; then | |
| curl -sf "http://127.0.0.1:${PORT}/system/info" -o /dev/null 2>/dev/null && break | |
| elif have wget; then | |
| wget -qO /dev/null "http://127.0.0.1:${PORT}/system/info" 2>/dev/null && break | |
| fi | |
| # Check that backend process is still alive | |
| if ! kill -0 "$BACKEND_PID" 2>/dev/null; then | |
| printf "${C_ERR}β Backend process exited unexpectedly.${C_RST}\n" >&2 | |
| echo " Last 20 lines of log:" >&2 | |
| tail -n 20 "$LOG_FILE" >&2 || true | |
| exit 1 | |
| fi | |
| sleep 1 | |
| _elapsed=$((_elapsed + 1)) | |
| done | |
| # Final health check | |
| _healthy=false | |
| if have curl; then | |
| curl -sf "http://127.0.0.1:${PORT}/system/info" -o /dev/null 2>/dev/null && _healthy=true | |
| elif have wget; then | |
| wget -qO /dev/null "http://127.0.0.1:${PORT}/system/info" 2>/dev/null && _healthy=true | |
| fi | |
| if [ "$_healthy" != true ]; then | |
| printf "${C_ERR}β Backend didn't start in ${_deadline}s. See %s for errors.${C_RST}\n" "$LOG_FILE" >&2 | |
| tail -n 20 "$LOG_FILE" >&2 || true | |
| exit 1 | |
| fi | |
| URL="http://127.0.0.1:${PORT}/" | |
| echo "${C_OK}βΈ Backend up.${C_RST} Opening UI at ${C_OK}${URL}${C_RST}" | |
| # ββ Open browser (cross-platform) ββββββββββββββββββββββββββββββββββββββββββ | |
| if [ "$NO_OPEN" != true ]; then | |
| if [ "$OS" = "macos" ] && have open; then | |
| open "$URL" | |
| elif [ "$OS" = "wsl" ]; then | |
| # WSL: use Windows browser via PowerShell or cmd.exe | |
| if have powershell.exe; then | |
| powershell.exe -NoProfile -Command "Start-Process '$URL'" >/dev/null 2>&1 & | |
| elif have cmd.exe; then | |
| cmd.exe /c start "" "$URL" >/dev/null 2>&1 & | |
| elif have xdg-open; then | |
| xdg-open "$URL" >/dev/null 2>&1 & | |
| else | |
| echo " Open in your browser: $URL" | |
| fi | |
| elif have xdg-open; then | |
| xdg-open "$URL" >/dev/null 2>&1 & | |
| else | |
| echo " Open in your browser: $URL" | |
| fi | |
| fi | |
| echo "" | |
| echo "OmniVoice Studio is running." | |
| echo "Press Ctrl+C to shut down." | |
| # Block until user hits Ctrl+C or backend exits. | |
| wait "$BACKEND_PID" | |