#!/bin/bash
# Wirecore Process Manager
# Simple, explicit process management for development and production
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Ensure we're using Node v20
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
nvm use 20.11.0 >/dev/null 2>&1 || {
echo "ERROR: Node v20.11.0 not found. Install with: nvm install 20.11.0"
exit 1
}
# PID files
SERVER_PID_FILE="/tmp/wirecore-server.pid"
CLODE_PID_FILE="/tmp/wirecore-clode.pid"
# Log files
SERVER_LOG="/tmp/wirecore-server.log"
CLODE_LOG="/tmp/wirecore-clode.log"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
#######################################
# Helper Functions
#######################################
is_running() {
local pid_file=$1
if [ -f "$pid_file" ]; then
local pid=$(cat "$pid_file")
if ps -p "$pid" > /dev/null 2>&1; then
return 0
else
rm -f "$pid_file"
return 1
fi
fi
return 1
}
start_server() {
if is_running "$SERVER_PID_FILE"; then
echo -e "${YELLOW}Server already running (PID: $(cat $SERVER_PID_FILE))${NC}"
return 0
fi
echo -e "${BLUE}Starting Wirecore Web Server...${NC}"
node lib/server/index.js > "$SERVER_LOG" 2>&1 &
echo $! > "$SERVER_PID_FILE"
sleep 2
if is_running "$SERVER_PID_FILE"; then
echo -e "${GREEN}✓ Server started (PID: $(cat $SERVER_PID_FILE))${NC}"
echo -e " Logs: tail -f $SERVER_LOG"
return 0
else
echo -e "${RED}✗ Server failed to start${NC}"
echo -e " Check logs: cat $SERVER_LOG"
return 1
fi
}
start_clode() {
if is_running "$CLODE_PID_FILE"; then
echo -e "${YELLOW}Clode bot already running (PID: $(cat $CLODE_PID_FILE))${NC}"
return 0
fi
echo -e "${BLUE}Starting Clode Bot...${NC}"
node bots/clode/stay-online.js > "$CLODE_LOG" 2>&1 &
echo $! > "$CLODE_PID_FILE"
sleep 2
if is_running "$CLODE_PID_FILE"; then
echo -e "${GREEN}✓ Clode started (PID: $(cat $CLODE_PID_FILE))${NC}"
echo -e " Logs: tail -f $CLODE_LOG"
return 0
else
echo -e "${RED}✗ Clode failed to start${NC}"
echo -e " Check logs: cat $CLODE_LOG"
return 1
fi
}
stop_process() {
local pid_file=$1
local name=$2
if ! is_running "$pid_file"; then
echo -e "${YELLOW}$name not running${NC}"
return 0
fi
local pid=$(cat "$pid_file")
echo -e "${BLUE}Stopping $name (PID: $pid)...${NC}"
kill "$pid" 2>/dev/null || true
# Wait up to 5 seconds for graceful shutdown
for i in {1..10}; do
if ! ps -p "$pid" > /dev/null 2>&1; then
rm -f "$pid_file"
echo -e "${GREEN}✓ $name stopped${NC}"
return 0
fi
sleep 0.5
done
# Force kill if still running
echo -e "${YELLOW}Force killing $name...${NC}"
kill -9 "$pid" 2>/dev/null || true
rm -f "$pid_file"
echo -e "${GREEN}✓ $name stopped${NC}"
}
status() {
echo -e "${BLUE}Wirecore Process Status${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Server status
if is_running "$SERVER_PID_FILE"; then
local pid=$(cat "$SERVER_PID_FILE")
local mem=$(ps -p "$pid" -o rss= | awk '{print int($1/1024)"MB"}')
echo -e "${GREEN}✓${NC} Server: RUNNING (PID: $pid, MEM: $mem)"
echo " Logs: $SERVER_LOG"
# Test if server responds
if curl -s http://localhost:3000/health >/dev/null 2>&1; then
echo -e " Health: ${GREEN}OK${NC} (http://localhost:3000)"
else
echo -e " Health: ${RED}NOT RESPONDING${NC}"
fi
else
echo -e "${RED}✗${NC} Server: STOPPED"
fi
echo ""
# Clode status
if is_running "$CLODE_PID_FILE"; then
local pid=$(cat "$CLODE_PID_FILE")
local mem=$(ps -p "$pid" -o rss= | awk '{print int($1/1024)"MB"}')
echo -e "${GREEN}✓${NC} Clode: RUNNING (PID: $pid, MEM: $mem)"
echo " Logs: $CLODE_LOG"
else
echo -e "${RED}✗${NC} Clode: STOPPED"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
}
logs() {
local service=$1
case "$service" in
server)
echo -e "${BLUE}Server logs (Ctrl+C to exit):${NC}"
tail -f "$SERVER_LOG"
;;
clode)
echo -e "${BLUE}Clode logs (Ctrl+C to exit):${NC}"
tail -f "$CLODE_LOG"
;;
*)
echo -e "${BLUE}Recent logs:${NC}"
echo -e "\n${YELLOW}=== Server ===${NC}"
tail -20 "$SERVER_LOG" 2>/dev/null || echo "No logs yet"
echo -e "\n${YELLOW}=== Clode ===${NC}"
tail -20 "$CLODE_LOG" 2>/dev/null || echo "No logs yet"
;;
esac
}
#######################################
# Commands
#######################################
case "${1:-}" in
start)
case "${2:-all}" in
server)
start_server
;;
clode)
start_clode
;;
all)
start_server && start_clode
;;
*)
echo "Usage: $0 start [server|clode|all]"
exit 1
;;
esac
;;
stop)
case "${2:-all}" in
server)
stop_process "$SERVER_PID_FILE" "Server"
;;
clode)
stop_process "$CLODE_PID_FILE" "Clode"
;;
all)
stop_process "$SERVER_PID_FILE" "Server"
stop_process "$CLODE_PID_FILE" "Clode"
;;
*)
echo "Usage: $0 stop [server|clode|all]"
exit 1
;;
esac
;;
restart)
case "${2:-all}" in
server)
stop_process "$SERVER_PID_FILE" "Server"
start_server
;;
clode)
stop_process "$CLODE_PID_FILE" "Clode"
start_clode
;;
all)
stop_process "$SERVER_PID_FILE" "Server"
stop_process "$CLODE_PID_FILE" "Clode"
start_server && start_clode
;;
*)
echo "Usage: $0 restart [server|clode|all]"
exit 1
;;
esac
;;
status)
status
;;
logs)
logs "${2:-all}"
;;
*)
echo -e "${BLUE}Wirecore Process Manager${NC}"
echo ""
echo "Usage: $0 COMMAND [TARGET]"
echo ""
echo "Commands:"
echo " start [server|clode|all] - Start services"
echo " stop [server|clode|all] - Stop services"
echo " restart [server|clode|all] - Restart services"
echo " status - Show status"
echo " logs [server|clode|all] - Show logs"
echo ""
echo "Examples:"
echo " $0 start # Start everything"
echo " $0 start server # Start only web server"
echo " $0 stop all # Stop everything"
echo " $0 restart server # Restart web server"
echo " $0 status # Check what's running"
echo " $0 logs server # Follow server logs"
exit 1
;;
esac