maestro/scripts/server.sh
oss-sync c526adddc2
Some checks failed
CI / build-and-test (push) Has been cancelled
sync: update from private repo (402599f)
2026-06-04 13:41:33 +00:00

138 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
PID_FILE="$PROJECT_DIR/.server.pid"
LOG_FILE="$PROJECT_DIR/logs/server.log"
PORT="${PORT:-9876}"
cd "$PROJECT_DIR"
usage() {
echo "Usage: $0 {start|stop|restart|status|logs}"
exit 1
}
is_running() {
if [[ -f "$PID_FILE" ]]; then
local pid
pid=$(cat "$PID_FILE")
if kill -0 "$pid" 2>/dev/null; then
return 0
fi
rm -f "$PID_FILE"
fi
return 1
}
do_start() {
if is_running; then
echo "Server already running (PID $(cat "$PID_FILE"))"
return 0
fi
# Surface stray maestro processes the pidfile doesn't track (e.g. an orphaned
# run on another port/mode that a previous restart never stopped). The
# app-level worker lock (src/instance-lock.ts) will refuse to double-start
# worker mode against the same DB, but warn here so the operator notices.
local strays
strays=$(pgrep -f "node dist/main.js" 2>/dev/null | grep -vx "$$" || true)
if [[ -n "$strays" ]]; then
echo "WARNING: other 'node dist/main.js' process(es) detected (PID: $(echo "$strays" | tr '\n' ' '))."
echo " If a previous run was not stopped cleanly, stop it first to avoid port/DB conflicts."
fi
mkdir -p "$(dirname "$LOG_FILE")"
echo "Checking runtime dependencies..."
"$SCRIPT_DIR/prepare.sh"
echo "Building..."
npm run build --silent 2>&1 | tail -1
echo "Starting server on port $PORT..."
# AAO is a single binary with two modes (dist/main.js dispatches):
# AAO_MODE=worker (default) — full orchestrator (DB + bridge API + workers)
# AAO_MODE=gateway — OpenAI-compatible LLM gateway only
# To launch as a gateway: `AAO_MODE=gateway scripts/server.sh start` and
# set `gateway.listen_port` in config.yaml (default 4000). dist/index.js
# is preserved as a worker-mode shim for legacy paths.
PORT="$PORT" AAO_MODE="${AAO_MODE:-worker}" nohup node dist/main.js >> "$LOG_FILE" 2>&1 &
local pid=$!
echo "$pid" > "$PID_FILE"
# Wait briefly and verify it started
sleep 2
if kill -0 "$pid" 2>/dev/null; then
echo "Server started (PID $pid, log: $LOG_FILE)"
else
rm -f "$PID_FILE"
echo "Server failed to start. Check $LOG_FILE"
tail -5 "$LOG_FILE"
return 1
fi
}
do_stop() {
if ! is_running; then
echo "Server not running"
# Also kill any stray process on the port
local stray
stray=$(lsof -ti:"$PORT" 2>/dev/null || true)
if [[ -n "$stray" ]]; then
echo "Found stray process on port $PORT (PID $stray), killing..."
kill "$stray" 2>/dev/null || true
fi
return 0
fi
local pid
pid=$(cat "$PID_FILE")
echo "Stopping server (PID $pid)..."
kill "$pid" 2>/dev/null || true
# Wait for graceful shutdown
for i in {1..10}; do
if ! kill -0 "$pid" 2>/dev/null; then
rm -f "$PID_FILE"
echo "Server stopped"
return 0
fi
sleep 0.5
done
# Force kill
echo "Force killing..."
kill -9 "$pid" 2>/dev/null || true
rm -f "$PID_FILE"
echo "Server stopped (forced)"
}
do_status() {
if is_running; then
local pid
pid=$(cat "$PID_FILE")
echo "Server running (PID $pid, port $PORT)"
else
echo "Server not running"
fi
}
do_logs() {
if [[ -f "$LOG_FILE" ]]; then
tail -f "$LOG_FILE"
else
echo "No log file found at $LOG_FILE"
fi
}
case "${1:-}" in
start) do_start ;;
stop) do_stop ;;
restart) do_stop; do_start ;;
status) do_status ;;
logs) do_logs ;;
*) usage ;;
esac