#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" PORT="${WEB_UI_PORT:-8765}" LABEL="com.james.autotrain.web-ui" PLIST="$HOME/Library/LaunchAgents/$LABEL.plist" LOG_FILE="$ROOT_DIR/work/web_ui.log" PID_FILE="$ROOT_DIR/work/web_ui.pid" LAUNCHD_TARGET="gui/$(id -u)/$LABEL" PYTHON_BIN="$(python3 -c 'import sys; print(sys.executable)')" mkdir -p "$ROOT_DIR/work" "$HOME/Library/LaunchAgents" echo "[web-ui] project: $ROOT_DIR" echo "[web-ui] python: $PYTHON_BIN" echo "[web-ui] installing launch agent: $PLIST" launchctl bootout "gui/$(id -u)" "$PLIST" >/dev/null 2>&1 || true PIDS="$(lsof -tiTCP:"$PORT" -sTCP:LISTEN 2>/dev/null || true)" if [[ -n "$PIDS" ]]; then echo "[web-ui] stopping old listener on :$PORT -> $PIDS" kill $PIDS 2>/dev/null || true sleep 1 fi cat > "$PLIST" < Label $LABEL ProgramArguments $PYTHON_BIN -u $ROOT_DIR/scripts/web_ui.py WorkingDirectory $ROOT_DIR RunAtLoad KeepAlive StandardOutPath $LOG_FILE StandardErrorPath $LOG_FILE EnvironmentVariables PYTHONUNBUFFERED 1 PLIST launchctl bootstrap "gui/$(id -u)" "$PLIST" launchctl kickstart -k "$LAUNCHD_TARGET" for _ in {1..30}; do if curl -fsS --max-time 2 "http://127.0.0.1:$PORT/" >/dev/null; then PID="$(lsof -tiTCP:"$PORT" -sTCP:LISTEN 2>/dev/null | head -n 1 || true)" [[ -n "$PID" ]] && echo "$PID" > "$PID_FILE" echo "[web-ui] ready: http://127.0.0.1:$PORT" echo "[web-ui] managed by: $LABEL" echo "[web-ui] pid: ${PID:-unknown}" echo "[web-ui] log: $LOG_FILE" exit 0 fi sleep 0.2 done echo "[web-ui] launch agent startup timeout. log: $LOG_FILE" >&2 tail -80 "$LOG_FILE" >&2 || true exit 1