#!/usr/bin/env bash set -euo pipefail find_lab_root(){ if [[ -n "${AZEROTHAI_PLAYABLE_ROOT:-}" && -d "$AZEROTHAI_PLAYABLE_ROOT" ]]; then printf '%s' "$AZEROTHAI_PLAYABLE_ROOT"; return fi for root in "$HOME/azerothai-pc-lab" "$HOME/azerothai-playable"; do if [[ -d "$root" ]]; then printf '%s' "$root"; return; fi done printf '%s' "$HOME/azerothai-playable" } LAB_ROOT="$(find_lab_root)" ACORE_ROOT="$LAB_ROOT/azerothcore" RUNTIME_ENV="$LAB_ROOT/runtime.env" if [[ -f "$RUNTIME_ENV" ]]; then # shellcheck disable=SC1090 source "$RUNTIME_ENV" fi echo "AzerothAI playable lab status" echo "================================" echo "Lab root : $LAB_ROOT" if [[ -f "$LAB_ROOT/azerothai.pid" ]] && kill -0 "$(cat "$LAB_ROOT/azerothai.pid")" 2>/dev/null; then echo "AzerothAI process : running (PID $(cat "$LAB_ROOT/azerothai.pid"))" else echo "AzerothAI process : stopped" fi if sudo systemctl is-active --quiet azerothai-autonomy.service 2>/dev/null; then PID="$(sudo systemctl show -p MainPID --value azerothai-autonomy.service)" echo "Autonomy worker : running via systemd (PID $PID)" elif [[ -f "$LAB_ROOT/autonomy.pid" ]] && kill -0 "$(cat "$LAB_ROOT/autonomy.pid")" 2>/dev/null; then echo "Autonomy worker : running legacy PID $(cat "$LAB_ROOT/autonomy.pid")" else echo "Autonomy worker : stopped" fi if sudo systemctl is-active --quiet azerothai-ale-relay.service 2>/dev/null; then RELAY_PID="$(sudo systemctl show -p MainPID --value azerothai-ale-relay.service)" echo "ALE DB relay : running via systemd (PID $RELAY_PID)" else echo "ALE DB relay : stopped" fi if curl -fsS http://127.0.0.1:8787/api/health >/tmp/azerothai-health.json 2>/dev/null; then echo "Dashboard health : OK" if command -v jq >/dev/null 2>&1; then jq -c . /tmp/azerothai-health.json else cat /tmp/azerothai-health.json fi echo else echo "Dashboard health : unavailable" fi if curl -fsS http://127.0.0.1:8787/api/world-monitor >/tmp/azerothai-world-monitor.json 2>/dev/null; then echo echo "Live realm monitor:" if command -v jq >/dev/null 2>&1; then jq -r ' " ALE bridge ready : " + ((.ale.bridgeReady // false)|tostring), " ALE active recently : " + ((.ale.activeRecently // false)|tostring), " Observed bot events : " + ((.playerbots.observedBots // 0)|tostring), " ALE pending commands : " + ((.commands.pending // 0)|tostring), " ALE failed commands : " + ((.commands.failed // 0)|tostring) ' /tmp/azerothai-world-monitor.json else cat /tmp/azerothai-world-monitor.json fi fi if curl -fsS http://127.0.0.1:8787/api/state >/tmp/azerothai-state.json 2>/dev/null && command -v jq >/dev/null 2>&1; then MANAGED="$(jq '[.bots[]? | select(.autonomy.managed == true)] | length' /tmp/azerothai-state.json 2>/dev/null || echo 0)" DUE="$(jq '[.bots[]? | select(.autonomy.managed == true and .status != "dead" and .status != "retired")] | length' /tmp/azerothai-state.json 2>/dev/null || echo 0)" echo " Managed AzerothAI lives : $MANAGED" echo " Managed living residents: $DUE" fi if [[ -d "$ACORE_ROOT" ]]; then echo echo "WoW containers:" (cd "$ACORE_ROOT" && docker compose ps) || true if docker inspect ac-database >/dev/null 2>&1 && [[ -n "${DOCKER_DB_ROOT_PASSWORD:-}" ]]; then echo echo "Realm:" docker exec ac-database mysql -uroot -p"$DOCKER_DB_ROOT_PASSWORD" -Nse "SELECT CONCAT(name,' | ',address,':',port,' | build ',gamebuild) FROM acore_auth.realmlist WHERE id=1" 2>/dev/null || true RND_ACCOUNTS="$(docker exec ac-database mysql -uroot -p"$DOCKER_DB_ROOT_PASSWORD" -Nse "SELECT COUNT(*) FROM acore_auth.account WHERE UPPER(username) LIKE 'RNDBOT%'" 2>/dev/null || echo '?')" RND_ONLINE="$(docker exec ac-database mysql -uroot -p"$DOCKER_DB_ROOT_PASSWORD" -Nse "SELECT COUNT(*) FROM acore_characters.characters c JOIN acore_auth.account a ON a.id=c.account WHERE c.online=1 AND UPPER(a.username) LIKE 'RNDBOT%'" 2>/dev/null || echo '?')" echo "Random bot accounts: $RND_ACCOUNTS" echo "Random bots online : $RND_ONLINE" if docker exec ac-database mysql -uroot -p"$DOCKER_DB_ROOT_PASSWORD" -Nse "SELECT 1 FROM information_schema.tables WHERE table_schema='acore_auth' AND table_name='azerothai_command_inbox'" 2>/dev/null | grep -q 1; then SPOOL_COMMANDS="$(docker exec ac-database mysql -uroot -p"$DOCKER_DB_ROOT_PASSWORD" -Nse "SELECT COUNT(*) FROM acore_auth.azerothai_command_inbox WHERE consumed_at IS NULL" 2>/dev/null || echo '?')" SPOOL_EVENTS="$(docker exec ac-database mysql -uroot -p"$DOCKER_DB_ROOT_PASSWORD" -Nse "SELECT COUNT(*) FROM acore_auth.azerothai_event_outbox WHERE delivered_at IS NULL" 2>/dev/null || echo '?')" SPOOL_RESULTS="$(docker exec ac-database mysql -uroot -p"$DOCKER_DB_ROOT_PASSWORD" -Nse "SELECT COUNT(*) FROM acore_auth.azerothai_result_outbox WHERE delivered_at IS NULL" 2>/dev/null || echo '?')" echo "ALE spool commands : $SPOOL_COMMANDS" echo "ALE spool events : $SPOOL_EVENTS" echo "ALE spool results : $SPOOL_RESULTS" fi fi echo echo "Listening ports:" for port in 3724 8085 8787; do if command -v ss >/dev/null 2>&1 && ss -ltn | awk '{print $4}' | grep -Eq "[:.]$port$"; then echo " $port/tcp : listening" else echo " $port/tcp : not detected" fi done else echo "WoW server : not bootstrapped" fi if [[ -n "${ALE_OPERATOR_TOKEN:-}" ]]; then echo if curl -fsS -H "Authorization: Bearer $ALE_OPERATOR_TOKEN" http://127.0.0.1:8787/api/ale/status >/tmp/azerothai-ale-status.json 2>/dev/null; then echo "ALE control plane : reachable" python3 - <<'PY' import json p='/tmp/azerothai-ale-status.json' d=json.load(open(p)) print("rawEnabled:",d.get("rawEnabled")) print("recent commands:",len(d.get("commands",[]))) print("recent events:",len(d.get("events",[]))) for e in d.get("events",[])[:5]: print(" -",e.get("at"),e.get("kind")) PY else echo "ALE control plane : unavailable" fi fi if [[ -f "$LAB_ROOT/autonomy.log" ]]; then echo echo "Recent autonomy:" tail -n 5 "$LAB_ROOT/autonomy.log" || true fi