deploy.sh 4.98 KB
#!/bin/bash
# deploy.sh — One-push deploy phoneuse code from Mac to Pixel + restart services
#
# Usage:
#   ./deploy.sh              # deploy all changed .py files + restart MCP
#   ./deploy.sh --no-restart # deploy only, don't restart services
#   ./deploy.sh --full       # deploy everything including APK rebuild
#
# Requires: adb in PATH, Pixel connected, rooted

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PLATFORM_TOOLS="${SCRIPT_DIR}/platform-tools"
ADB="${PLATFORM_TOOLS}/adb"
DEVICE_DIR="/data/data/com.termux/files/home/.hermes/event_bus"
LOG_DIR="/data/data/com.termux/files/home/.hermes/logs"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info()  { echo -e "${GREEN}[INFO]${NC} $*"; }
log_warn()  { echo -e "${YELLOW}[WARN]${NC} $*"; }
log_error() { echo -e "${RED}[ERROR]${NC} $*"; }

check_device() {
    if ! "$ADB" devices | grep -q "device$"; then
        log_error "No Pixel device connected. Run: ${ADB} devices"
        exit 1
    fi
    log_info "Device connected: $("$ADB" devices | grep 'device$' | awk '{print $1}')"
}

push_files() {
    local files=(
        android_mcp.py
        wechat_send.py
        ui_control_tools.py
        ocr_tools.py
        telephony_tools.py
        device_tools.py
        event_server.py
        memory_graph.py
        connectors.py
        persona.py
        cloud_knowledge.py
        mitm_proxy.py
        notification_monitor.py
        frida_bridge.py
    )

    log_info "Pushing ${#files[@]} files to Pixel..."
    for f in "${files[@]}"; do
        if [[ -f "${SCRIPT_DIR}/$f" ]]; then
            "$ADB" push "${SCRIPT_DIR}/$f" "/data/local/tmp/$f" >/dev/null
            "$ADB" shell "su -c 'cp /data/local/tmp/$f ${DEVICE_DIR}/ && chown u0_a302:u0_a302 ${DEVICE_DIR}/$f'" >/dev/null 2>&1 || \
                "$ADB" shell "su -c 'cp /data/local/tmp/$f ${DEVICE_DIR}/'" >/dev/null
            log_info "  ✓ $f"
        else
            log_warn "  ✗ $f (not found in repo)"
        fi
    done
}

restart_mcp() {
    log_info "Restarting MCP server..."
    # Kill existing android_mcp processes
    "$ADB" shell "su -c 'pkill -f android_mcp.py'" >/dev/null 2>&1 || true
    sleep 1
    # Start fresh
    "$ADB" shell "su -c 'export PATH=/data/data/com.termux/files/usr/bin:\$PATH; cd ${DEVICE_DIR} && nohup /data/data/com.termux/files/home/.hermes/hermes-agent/venv/bin/python3 android_mcp.py > ${LOG_DIR}/android_mcp.log 2>&1 &'" >/dev/null
    sleep 2
    local pid=$("$ADB" shell "ps -A -o PID,ARGS | grep android_mcp | grep -v grep | awk '{print \$1}'" | tr -d '\r')
    if [[ -n "$pid" ]]; then
        log_info "MCP restarted (PID: $pid)"
    else
        log_error "MCP failed to start. Check ${LOG_DIR}/android_mcp.log"
        exit 1
    fi
}

restart_event_server() {
    log_info "Restarting event_server..."
    "$ADB" shell "su -c 'pkill -f \"event_server:app\"'" >/dev/null 2>&1 || true
    sleep 1
    "$ADB" shell "su -c 'export PATH=/data/data/com.termux/files/usr/bin:\$PATH; cd ${DEVICE_DIR} && nohup python -m uvicorn event_server:app --host 127.0.0.1 --port 8765 --log-level warning > ${LOG_DIR}/event_server.log 2>&1 &'" >/dev/null
    sleep 1
    if "$ADB" shell "netstat -tlnp 2>/dev/null | grep -q ':8765'" >/dev/null 2>&1; then
        log_info "event_server restarted (port 8765)"
    else
        log_warn "event_server restart status unclear"
    fi
}

verify_tools() {
    log_info "Verifying tool count..."
    local count=$("$ADB" shell "su -c 'export PATH=/data/data/com.termux/files/usr/bin:\$PATH; cd ${DEVICE_DIR} && /data/data/com.termux/files/home/.hermes/hermes-agent/venv/bin/python3 -c \"import sys; sys.path.insert(0, \"\"\".\"\"\"); from android_mcp import _build_server; s=_build_server(); print(len(s._tool_manager._tools))\"'" | tr -d '\r')
    log_info "Registered tools: $count"
    if [[ "$count" -lt 50 ]]; then
        log_warn "Tool count seems low. Expected 50+"
    fi
}

# ── main ────────────────────────────────────────────────────────────────────

NO_RESTART=false
FULL=false

for arg in "$@"; do
    case "$arg" in
        --no-restart) NO_RESTART=true ;;
        --full)       FULL=true ;;
        -h|--help)
            echo "Usage: $0 [--no-restart] [--full]"
            echo "  --no-restart  Deploy files only, don't restart services"
            echo "  --full        Also rebuild and install APK"
            exit 0
            ;;
    esac
done

check_device
push_files

if [[ "$NO_RESTART" == false ]]; then
    restart_mcp
    restart_event_server
    verify_tools
    log_info "Deploy complete! Hermes should reconnect to MCP automatically."
else
    log_info "Files deployed. Services NOT restarted (use --no-restart flag)."
fi

if [[ "$FULL" == true ]]; then
    log_warn "APK rebuild not yet implemented in this script."
    log_warn "Run: cd android && ./gradlew assembleDebug && adb install app/build/outputs/apk/debug/app-debug.apk"
fi