feat: publish workphone SDK deployment and API docs

This commit is contained in:
Manus AI
2026-07-14 18:10:52 +08:00
commit 021d633cc1
534 changed files with 122391 additions and 0 deletions

165
sdk/scripts/lan_connect_setup.sh Executable file
View File

@@ -0,0 +1,165 @@
#!/usr/bin/env bash
# 局域网无线主控:本机局网 IP ↔ 手机同 WiFi ↔ Termux Agent / 无线 ADB
# 用法:
# bash sdk/scripts/lan_connect_setup.sh
# PHONE_IP=192.168.110.40 bash sdk/scripts/lan_connect_setup.sh
# bash sdk/scripts/lan_connect_setup.sh --connect # 尝试 adb connect 后 oneclick
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SDK_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
SDK_PORT="${WORKPHONE_SDK_PORT:-8899}"
DEVICE_ID="${DEVICE_ID:-xgfe65eimrrofyws}"
PHONE_IP="${PHONE_IP:-}"
ADB_PORT="${ANDROID_ADB_SERVER_PORT:-5038}"
ADB=(adb -P "${ADB_PORT}")
export ANDROID_ADB_SERVER_PORT="${ADB_PORT}"
LAN_ENV="${SDK_ROOT}/config/lan.env"
DO_CONNECT=0
[[ "${1:-}" == "--connect" ]] && DO_CONNECT=1
pick_lan_ip() {
local ip
for ip in $(ifconfig | awk '/inet /{print $2}' | grep -v '^127\.'); do
[[ "$ip" == 198.18.* ]] && continue
[[ "$ip" == 192.168.110.* ]] && { echo "$ip"; return; }
done
for ip in $(ifconfig | awk '/inet /{print $2}' | grep -v '^127\.'); do
[[ "$ip" == 198.18.* ]] && continue
[[ "$ip" == 192.168.* ]] && { echo "$ip"; return; }
done
ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || echo "127.0.0.1"
}
LAN_IP="$(pick_lan_ip)"
WS_URL="ws://${LAN_IP}:${SDK_PORT}/ws/device/${DEVICE_ID}"
API_URL="http://${LAN_IP}:${SDK_PORT}"
log() { echo "[lan] $*"; }
log "本机局网 IP: ${LAN_IP}"
log "SDK API: ${API_URL}"
log "Agent WS: ${WS_URL}"
mkdir -p "${SDK_ROOT}/config"
cat >"${LAN_ENV}" <<EOF
# 自动生成 $(date '+%F %T') — source 后用于脚本
export WORKPHONE_LAN_IP=${LAN_IP}
export WORKPHONE_SDK_HOST=${LAN_IP}:${SDK_PORT}
export WORKPHONE_WS_URL=${WS_URL}
export WORKPHONE_API_URL=${API_URL}
export ANDROID_ADB_SERVER_PORT=${ADB_PORT}
export WIRELESS_IPS="${PHONE_IP:-192.168.110.40 192.168.110.80 192.168.110.236}"
EOF
log "已写入 ${LAN_ENV}"
# ── 1) SDK 本机 / 局网可达性 ──
"${ADB[@]}" start-server >/dev/null 2>&1 || true
SDK_VIA="local"
if docker ps --format '{{.Names}}' 2>/dev/null | grep -qx workphone-sdk; then
SDK_VIA="docker"
log "SDK 由 Docker workphone-sdk 提供 :${SDK_PORT}"
if ! curl -sf --max-time 5 "http://127.0.0.1:${SDK_PORT}/health" >/dev/null 2>&1; then
log "Docker SDK 未响应,尝试 adb 桥接后重启容器…"
bash "${SCRIPT_DIR}/adb_host_server_listen_all.sh" --background || true
(cd "${SDK_ROOT}" && ADB_SERVER_SOCKET="tcp:host.docker.internal:${ADB_PORT}" docker compose up -d workphone-sdk) || true
sleep 4
fi
elif curl -sf --max-time 3 "http://127.0.0.1:${SDK_PORT}/health" >/dev/null 2>&1; then
log "SDK localhost:${SDK_PORT} ✅ (${SDK_VIA})"
else
log "SDK 未运行 → 启动 uvicorn 0.0.0.0:${SDK_PORT}"
cd "${SDK_ROOT}/app"
nohup env ANDROID_ADB_SERVER_PORT="${ADB_PORT}" python3 -m uvicorn main:app \
--host 0.0.0.0 --port "${SDK_PORT}" >>"${SDK_ROOT}/logs/sdk.log" 2>&1 &
sleep 3
fi
if [[ "$SDK_VIA" == "docker" ]]; then
bash "${SCRIPT_DIR}/adb_host_server_listen_all.sh" --background || true
fi
if curl -sf --max-time 5 "${API_URL}/health" >/dev/null 2>&1; then
log "SDK 局网 ${API_URL}/health ✅"
else
log "⚠️ 局网 ${API_URL} 不可达 — 检查 Mac 防火墙是否放行 ${SDK_PORT},或确认手机与 Mac 同网段"
fi
# ── 2) 探测手机(同网段 5555──
try_adb_connect() {
local host="$1" port="${2:-5555}"
local target="${host}:${port}"
"${ADB[@]}" connect "${target}" >/dev/null 2>&1 || true
sleep 2
if "${ADB[@]}" -s "${target}" get-state 2>/dev/null | grep -qx device; then
printf '%s' "${target}"
return 0
fi
"${ADB[@]}" disconnect "${target}" >/dev/null 2>&1 || true
return 1
}
FOUND=""
ADB_SERIAL=""
if [[ -n "$PHONE_IP" ]]; then
if try_adb_connect "$PHONE_IP" >/dev/null; then
ADB_SERIAL="${PHONE_IP}:5555"
FOUND="${ADB_SERIAL}"
fi
fi
if [[ -z "$FOUND" ]]; then
for ip in 192.168.110.40 192.168.110.80 192.168.110.236 192.168.1.12; do
ping -c 1 -W 1 "$ip" >/dev/null 2>&1 || continue
if try_adb_connect "$ip" >/dev/null; then
ADB_SERIAL="${ip}:5555"
FOUND="${ADB_SERIAL}"
break
fi
done
fi
if [[ -n "$FOUND" ]]; then
log "无线 ADB 已连接: ${FOUND}"
else
log "暂未发现无线 ADB手机需开发者选项 → 无线调试 / 或 USB 执行一次 adb tcpip 5555"
fi
# ── 3) Termux 手机端命令(手机连本机 IP──
FRIDA_PORT="$(python3 -c "import json; print(json.load(open('${SCRIPT_DIR}/anti_detect/phantom_frida_config.json'))['listen_port'])" 2>/dev/null || echo 17263)"
echo ""
echo "================================================================"
echo " 手机 Termux 执行(与 Mac 同一 WiFi · 连 ${LAN_IP}"
echo "================================================================"
cat <<EOF
export WP_AGENT_ON_DEVICE=1
export WP_FRIDA_MODE=remote
export WP_FRIDA_PORT=${FRIDA_PORT}
export WP_SERVER_URL=${WS_URL}
cd ~/workphone/agent || cd ~/storage/downloads/workphone/agent
python agent.py -d ${DEVICE_ID} -s ${WS_URL} --heartbeat 10
# 或依赖 UDP 8898 自动发现(免手填 IP
# python agent.py -d ${DEVICE_ID} --heartbeat 10
EOF
echo "================================================================"
echo " Mac 验收"
echo "================================================================"
echo " curl ${API_URL}/health"
echo " curl ${API_URL}/api/v3/connection/status"
echo " curl ${API_URL}/api/v3/hook/probe/${DEVICE_ID}"
echo ""
if [[ "$DO_CONNECT" == "1" && -n "$ADB_SERIAL" ]]; then
log "执行 oneclick device=${ADB_SERIAL}"
DEVICE_SERIAL="$ADB_SERIAL" ANDROID_ADB_SERVER_PORT="${ADB_PORT}" \
bash "${SCRIPT_DIR}/frida_workphone_oneclick.sh" -d "$ADB_SERIAL" || true
fi
curl -s --max-time 5 "${API_URL}/api/v3/connection/status" 2>/dev/null | python3 -m json.tool 2>/dev/null | head -25 || true