Files

274 lines
8.3 KiB
Bash

#!/usr/bin/env bash
#
# OpenClaw Self-Healing System - One-Click Installer
# https://github.com/Ramsbaby/openclaw-self-healing
#
# Usage:
# curl -sSL https://raw.githubusercontent.com/Ramsbaby/openclaw-self-healing/main/install.sh | bash
#
# Or with custom OpenClaw workspace:
# curl -sSL https://raw.githubusercontent.com/Ramsbaby/openclaw-self-healing/main/install.sh | bash -s -- --workspace ~/my-openclaw
#
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Defaults
OPENCLAW_WORKSPACE="${OPENCLAW_WORKSPACE:-$HOME/openclaw}"
OPENCLAW_CONFIG_DIR="${OPENCLAW_CONFIG_DIR:-$HOME/.openclaw}"
REPO_URL="https://github.com/Ramsbaby/openclaw-self-healing"
REPO_RAW="https://raw.githubusercontent.com/Ramsbaby/openclaw-self-healing/main"
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--workspace)
OPENCLAW_WORKSPACE="$2"
shift 2
;;
--help|-h)
echo "Usage: $0 [--workspace PATH]"
echo ""
echo "Options:"
echo " --workspace PATH OpenClaw workspace directory (default: ~/openclaw)"
exit 0
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
exit 1
;;
esac
done
echo -e "${BLUE}"
echo "╔═══════════════════════════════════════════════════════════╗"
echo "║ 🦞 OpenClaw Self-Healing System Installer ║"
echo "║ \"The system that heals itself\" ║"
echo "╚═══════════════════════════════════════════════════════════╝"
echo -e "${NC}"
# Check OS
check_os() {
if [[ "$(uname)" != "Darwin" ]]; then
echo -e "${YELLOW}⚠️ This installer is optimized for macOS.${NC}"
echo -e "${YELLOW} For Linux, see: ${REPO_URL}/blob/main/docs/LINUX_SETUP.md${NC}"
echo ""
read -p "Continue anyway? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
}
# Check prerequisites
check_prerequisites() {
echo -e "${BLUE}[1/6] Checking prerequisites...${NC}"
local missing=()
# Check OpenClaw
if ! command -v openclaw &> /dev/null; then
missing+=("openclaw")
fi
# Check tmux
if ! command -v tmux &> /dev/null; then
missing+=("tmux")
fi
# Check Claude CLI
if ! command -v claude &> /dev/null; then
missing+=("claude (Claude Code CLI)")
fi
# Check curl
if ! command -v curl &> /dev/null; then
missing+=("curl")
fi
if [[ ${#missing[@]} -gt 0 ]]; then
echo -e "${RED}❌ Missing prerequisites:${NC}"
for item in "${missing[@]}"; do
echo " - $item"
done
echo ""
echo -e "${YELLOW}Install missing dependencies:${NC}"
echo " brew install tmux"
echo " npm install -g @anthropic-ai/claude-code"
echo " # OpenClaw: https://github.com/openclaw/openclaw"
exit 1
fi
echo -e "${GREEN}✅ All prerequisites found${NC}"
}
# Create directories
create_directories() {
echo -e "${BLUE}[2/6] Creating directories...${NC}"
mkdir -p "$OPENCLAW_WORKSPACE/scripts"
mkdir -p "$OPENCLAW_WORKSPACE/memory"
mkdir -p "$OPENCLAW_CONFIG_DIR"
mkdir -p "$HOME/Library/LaunchAgents"
echo -e "${GREEN}✅ Directories created${NC}"
}
# Download scripts
download_scripts() {
echo -e "${BLUE}[3/6] Downloading scripts...${NC}"
local scripts=(
"gateway-healthcheck.sh"
"emergency-recovery.sh"
"emergency-recovery-monitor.sh"
)
for script in "${scripts[@]}"; do
echo " Downloading $script..."
curl -sSL "$REPO_RAW/scripts/$script" -o "$OPENCLAW_WORKSPACE/scripts/$script"
chmod 700 "$OPENCLAW_WORKSPACE/scripts/$script"
done
echo -e "${GREEN}✅ Scripts downloaded${NC}"
}
# Setup environment
setup_environment() {
echo -e "${BLUE}[4/6] Setting up environment...${NC}"
local env_file="$OPENCLAW_CONFIG_DIR/.env"
if [[ -f "$env_file" ]]; then
echo -e "${YELLOW} .env already exists, preserving...${NC}"
else
cat > "$env_file" << 'EOF'
# OpenClaw Self-Healing System Configuration
# See: https://github.com/Ramsbaby/openclaw-self-healing
# Discord webhook for Level 4 alerts (optional)
# Get yours at: https://support.discord.com/hc/en-us/articles/228383668
# DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
# Gateway settings
OPENCLAW_GATEWAY_URL="http://localhost:18789/"
# Health Check settings
HEALTH_CHECK_MAX_RETRIES=3
HEALTH_CHECK_RETRY_DELAY=30
HEALTH_CHECK_ESCALATION_WAIT=300
# Emergency Recovery settings
EMERGENCY_RECOVERY_TIMEOUT=1800
CLAUDE_WORKSPACE_TRUST_TIMEOUT=10
# Alert settings
EMERGENCY_ALERT_WINDOW=30
EOF
chmod 600 "$env_file"
fi
echo -e "${GREEN}✅ Environment configured${NC}"
}
# Install LaunchAgent
install_launchagent() {
echo -e "${BLUE}[5/6] Installing LaunchAgent (Level 2 Health Check)...${NC}"
local plist="$HOME/Library/LaunchAgents/com.openclaw.healthcheck.plist"
# Unload if exists
if launchctl list | grep -q "com.openclaw.healthcheck"; then
launchctl unload "$plist" 2>/dev/null || true
fi
cat > "$plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.openclaw.healthcheck</string>
<key>ProgramArguments</key>
<array>
<string>$OPENCLAW_WORKSPACE/scripts/gateway-healthcheck.sh</string>
</array>
<key>StartInterval</key>
<integer>300</integer>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>$OPENCLAW_WORKSPACE/memory/healthcheck-stdout.log</string>
<key>StandardErrorPath</key>
<string>$OPENCLAW_WORKSPACE/memory/healthcheck-stderr.log</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
<key>HOME</key>
<string>$HOME</string>
</dict>
</dict>
</plist>
EOF
launchctl load "$plist"
echo -e "${GREEN}✅ LaunchAgent installed and loaded${NC}"
}
# Print summary
print_summary() {
echo -e "${BLUE}[6/6] Installation complete!${NC}"
echo ""
echo -e "${GREEN}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ 🎉 Self-Healing System Installed Successfully! ║${NC}"
echo -e "${GREEN}╚═══════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${BLUE}What's installed:${NC}"
echo " ✅ Level 1: Watchdog (use existing OpenClaw watchdog)"
echo " ✅ Level 2: Health Check (LaunchAgent, every 5 min)"
echo " ✅ Level 3: Claude Emergency Recovery (on-demand)"
echo " ✅ Level 4: Discord Alert (requires webhook setup)"
echo ""
echo -e "${BLUE}Scripts location:${NC}"
echo " $OPENCLAW_WORKSPACE/scripts/"
echo ""
echo -e "${BLUE}Configuration:${NC}"
echo " $OPENCLAW_CONFIG_DIR/.env"
echo ""
echo -e "${YELLOW}⚠️ Optional: Set up Level 4 Discord alerts${NC}"
echo " 1. Create a Discord webhook"
echo " 2. Edit $OPENCLAW_CONFIG_DIR/.env"
echo " 3. Add: DISCORD_WEBHOOK_URL=\"your-webhook-url\""
echo ""
echo -e "${BLUE}Verify installation:${NC}"
echo " launchctl list | grep openclaw.healthcheck"
echo " tail -f $OPENCLAW_WORKSPACE/memory/healthcheck-\$(date +%Y-%m-%d).log"
echo ""
echo -e "${BLUE}Documentation:${NC}"
echo " $REPO_URL"
echo ""
echo -e "${GREEN}The system is now watching your watcher. Sleep well. 🦞${NC}"
}
# Main
main() {
check_os
check_prerequisites
create_directories
download_scripts
setup_environment
install_launchagent
print_summary
}
main "$@"