#!/bin/bash # Dev Environment Orchestrator # Provides complete state detection and control for Claude Code set -eo pipefail SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) ROOT_DIR=$(cd "${SCRIPT_DIR}/.." && pwd) # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' ######################################### # STATE DETECTION ######################################### detect_backend_state() { local state="{}" # Check if pulse-backend service is running if systemctl is-active --quiet pulse-backend 2>/dev/null; then state=$(echo "$state" | jq '. + {backend_running: true, backend_type: "systemd"}') # Check mock mode from logs (multiple possible indicators, look at last 2 minutes for reliability) if sudo journalctl -u pulse-backend --since "2 minutes ago" | grep -qE "(Mock mode enabled|mockEnabled=true|mock mode trackedNodes)"; then state=$(echo "$state" | jq '. + {mock_mode: true}') else state=$(echo "$state" | jq '. + {mock_mode: false}') fi else state=$(echo "$state" | jq '. + {backend_running: false}') fi # Check what's configured in mock.env.local if [ -f "$ROOT_DIR/mock.env.local" ]; then if grep -q "PULSE_MOCK_MODE=true" "$ROOT_DIR/mock.env.local"; then state=$(echo "$state" | jq '. + {mock_configured: true}') else state=$(echo "$state" | jq '. + {mock_configured: false}') fi else # Check mock.env if grep -q "PULSE_MOCK_MODE=true" "$ROOT_DIR/mock.env" 2>/dev/null; then state=$(echo "$state" | jq '. + {mock_configured: true}') else state=$(echo "$state" | jq '. + {mock_configured: false}') fi fi echo "$state" } detect_frontend_state() { local state="{}" # Check if frontend dev server is running (Vite) if pgrep -f "vite.*7655" > /dev/null 2>&1; then state=$(echo "$state" | jq '. + {frontend_running: true, frontend_type: "vite-dev"}') elif [ -d "$ROOT_DIR/frontend-modern/dist" ]; then state=$(echo "$state" | jq '. + {frontend_running: false, frontend_built: true}') else state=$(echo "$state" | jq '. + {frontend_running: false, frontend_built: false}') fi echo "$state" } get_full_state() { local backend=$(detect_backend_state) local frontend=$(detect_frontend_state) echo "{}" | jq ". + {backend: $backend, frontend: $frontend}" } ######################################### # MODE SWITCHING ######################################### switch_to_mock() { echo -e "${YELLOW}Switching to mock mode...${NC}" # Update mock.env.local (preferred) or mock.env if [ -f "$ROOT_DIR/mock.env.local" ]; then sed -i 's/PULSE_MOCK_MODE=.*/PULSE_MOCK_MODE=true/' "$ROOT_DIR/mock.env.local" echo -e "${GREEN}✓ Updated mock.env.local${NC}" else sed -i 's/PULSE_MOCK_MODE=.*/PULSE_MOCK_MODE=true/' "$ROOT_DIR/mock.env" echo -e "${GREEN}✓ Updated mock.env${NC}" fi # Restart backend sudo systemctl restart pulse-backend echo -e "${GREEN}✓ Backend restarted${NC}" # Wait for backend to be ready sleep 3 # Verify if sudo journalctl -u pulse-backend --since "5 seconds ago" | grep -qE "(Mock mode enabled|mockEnabled=true|mock mode trackedNodes)"; then echo -e "${GREEN}✓ Mock mode ACTIVE${NC}" return 0 else echo -e "${RED}✗ Mock mode failed to activate${NC}" return 1 fi } switch_to_production() { echo -e "${YELLOW}Switching to production mode...${NC}" # Sync production config first if [ -f "$ROOT_DIR/scripts/sync-production-config.sh" ]; then echo "Syncing production configuration..." "$ROOT_DIR/scripts/sync-production-config.sh" fi # Update mock.env.local (preferred) or mock.env if [ -f "$ROOT_DIR/mock.env.local" ]; then sed -i 's/PULSE_MOCK_MODE=.*/PULSE_MOCK_MODE=false/' "$ROOT_DIR/mock.env.local" echo -e "${GREEN}✓ Updated mock.env.local${NC}" else sed -i 's/PULSE_MOCK_MODE=.*/PULSE_MOCK_MODE=false/' "$ROOT_DIR/mock.env" echo -e "${GREEN}✓ Updated mock.env${NC}" fi # Restart backend sudo systemctl restart pulse-backend echo -e "${GREEN}✓ Backend restarted${NC}" # Wait for backend to be ready sleep 3 echo -e "${GREEN}✓ Production mode ACTIVE${NC}" return 0 } ######################################### # FRONTEND MANAGEMENT ######################################### rebuild_frontend() { echo -e "${YELLOW}Rebuilding frontend...${NC}" cd "$ROOT_DIR/frontend-modern" npm run build echo -e "${GREEN}✓ Frontend rebuilt${NC}" } ######################################### # COMMANDS ######################################### cmd_status() { local state=$(get_full_state) echo -e "${BLUE}=== Dev Environment Status ===${NC}" echo "" # Backend local backend_running=$(echo "$state" | jq -r '.backend.backend_running') local backend_type=$(echo "$state" | jq -r '.backend.backend_type // "none"') local mock_mode=$(echo "$state" | jq -r '.backend.mock_mode // false') local mock_configured=$(echo "$state" | jq -r '.backend.mock_configured // false') echo -e "${BLUE}Backend:${NC}" if [ "$backend_running" = "true" ]; then echo -e " Status: ${GREEN}Running${NC} ($backend_type)" if [ "$mock_mode" = "true" ]; then echo -e " Mode: ${GREEN}Mock${NC}" else echo -e " Mode: ${YELLOW}Production${NC}" fi else echo -e " Status: ${RED}Stopped${NC}" fi echo -e " Configured: $([ "$mock_configured" = "true" ] && echo -e "${GREEN}Mock${NC}" || echo -e "${YELLOW}Production${NC}")" # Frontend local frontend_running=$(echo "$state" | jq -r '.frontend.frontend_running') local frontend_type=$(echo "$state" | jq -r '.frontend.frontend_type // "none"') local frontend_built=$(echo "$state" | jq -r '.frontend.frontend_built // false') echo "" echo -e "${BLUE}Frontend:${NC}" if [ "$frontend_running" = "true" ]; then echo -e " Status: ${GREEN}Running${NC} ($frontend_type)" else echo -e " Status: ${RED}Not running${NC}" echo -e " Built: $([ "$frontend_built" = "true" ] && echo -e "${GREEN}Yes${NC}" || echo -e "${RED}No${NC}")" fi # JSON output for Claude if [ "$1" = "--json" ]; then echo "" echo "$state" fi } cmd_mock() { switch_to_mock } cmd_prod() { switch_to_production } cmd_restart() { echo -e "${YELLOW}Restarting backend...${NC}" sudo systemctl restart pulse-backend sleep 2 echo -e "${GREEN}✓ Backend restarted${NC}" } cmd_help() { cat << EOF Dev Environment Orchestrator Usage: $0 Commands: status [--json] Show current environment state mock Switch to mock mode prod Switch to production mode restart Restart backend service help Show this help Examples: $0 status # Human-readable status $0 status --json # JSON output for automation $0 mock # Switch to mock mode $0 prod # Switch to production mode EOF } ######################################### # MAIN ######################################### case "${1:-status}" in status) cmd_status "$2" ;; mock) cmd_mock ;; prod) cmd_prod ;; restart) cmd_restart ;; help|--help|-h) cmd_help ;; *) echo "Unknown command: $1" cmd_help exit 1 ;; esac