#!/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 frida_inspect_tools.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