feat(mobile): termux-bootstrap.sh + robust ADB serial detection

termux-bootstrap.sh: one-shot on-device installer (pkg cryptography to avoid a
rust build, pure/wheeled pip deps, no srp C-ext, wake-lock, hh alias, Phase-0
preflight) — verified green on the Fairphone.

phone-capture.sh: auto-detect the adb device serial instead of assuming :5555,
since Wireless Debugging uses a dynamic port; target that serial for
screencap/screenrecord/pull. Clarified the pairing help to use the Tailscale IP.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
leetcrypt
2026-07-07 22:39:47 -07:00
parent e97a45b78d
commit 3a90ee985a
2 changed files with 94 additions and 9 deletions
+15 -9
View File
@@ -42,15 +42,19 @@ _ship(){ # <file>
[ -x "$TG_SEND" ] || _die "tg-send.sh not found at $TG_SEND" [ -x "$TG_SEND" ] || _die "tg-send.sh not found at $TG_SEND"
echo "→ Telegram ($TGT): $1"; "$TG_SEND" "$1" "$TGT" "phone capture $TS" echo "→ Telegram ($TGT): $1"; "$TG_SEND" "$1" "$TGT" "phone capture $TS"
} }
_adb_ready(){ adb devices 2>/dev/null | grep -qE "$IP.*device$"; } # first fully-authorized adb device serial (wireless debugging uses a dynamic
# port, so don't assume :5555 — read whatever 'adb devices' actually shows)
_adb_serial(){ adb devices 2>/dev/null | awk '$2=="device"{print $1; exit}'; }
_adb_ready(){ [ -n "$(_adb_serial)" ]; }
_adb_help(){ _adb_help(){
cat >&2 <<EOF cat >&2 <<EOF
ADB not connected. One-time setup on the phone: ADB not connected. One-time setup on the phone (ports are shown on-device;
the IP can be the Tailscale IP $IP since adbd binds all interfaces):
1. Settings → System → Developer options → Wireless debugging: ON 1. Settings → System → Developer options → Wireless debugging: ON
2. Tap "Pair device with pairing code" — note the IP:PORT and 6-digit code 2. Tap "Pair device with pairing code" — note the PAIR_PORT and 6-digit code
3. On the laptop: adb pair <IP>:<PAIR_PORT> (enter the code) 3. On the laptop: adb pair $IP:<PAIR_PORT> (enter the code)
4. Then: adb connect $IP:<DEBUG_PORT> (the port under Wireless debugging) 4. Then: adb connect $IP:<DEBUG_PORT> (port under "Wireless debugging")
Re-run this command once 'adb devices' shows $IP as 'device'. Re-run this command once 'adb devices' shows a 'device' line.
EOF EOF
} }
@@ -73,16 +77,18 @@ case "$cmd" in
shot) shot)
loc="${1:-$OUTDIR/phone-shot-$TS.png}" loc="${1:-$OUTDIR/phone-shot-$TS.png}"
_adb_ready || { _adb_help; exit 1; } _adb_ready || { _adb_help; exit 1; }
adb -s "$IP:5555" exec-out screencap -p > "$loc" 2>/dev/null || adb exec-out screencap -p > "$loc" dev="$(_adb_serial)"
adb -s "$dev" exec-out screencap -p > "$loc"
[ -s "$loc" ] || _die "screencap produced no data" [ -s "$loc" ] || _die "screencap produced no data"
echo "device screenshot → $loc"; _ship "$loc" echo "device screenshot → $loc"; _ship "$loc"
;; ;;
screen) screen)
secs="${1:-15}"; loc="${2:-$OUTDIR/phone-screen-$TS.mp4}" secs="${1:-15}"; loc="${2:-$OUTDIR/phone-screen-$TS.mp4}"
_adb_ready || { _adb_help; exit 1; } _adb_ready || { _adb_help; exit 1; }
dev="$(_adb_serial)"
echo "recording ${secs}s of the device screen…" echo "recording ${secs}s of the device screen…"
adb shell screenrecord --time-limit "$secs" /sdcard/hh-rec.mp4 adb -s "$dev" shell screenrecord --time-limit "$secs" /sdcard/hh-rec.mp4
adb pull /sdcard/hh-rec.mp4 "$loc" >/dev/null && adb shell rm -f /sdcard/hh-rec.mp4 adb -s "$dev" pull /sdcard/hh-rec.mp4 "$loc" >/dev/null && adb -s "$dev" shell rm -f /sdcard/hh-rec.mp4
echo "device screen recording → $loc"; _ship "$loc" echo "device screen recording → $loc"; _ship "$loc"
;; ;;
webshot) webshot)
+79
View File
@@ -0,0 +1,79 @@
#!/data/data/com.termux/files/usr/bin/bash
# termux-bootstrap.sh — one-shot on-device setup for the hack-house mobile
# operator. Run this IN TERMUX on the phone (not on the laptop):
#
# bash ~/hh-mobile/scripts/termux-bootstrap.sh
#
# It installs the deps that actually work on aarch64 Termux (cryptography from
# the package repo to dodge a rust build; pure/wheeled pip deps; NO `srp` — the
# pure-Python shim covers both client and server), holds a wake-lock so Android
# doesn't kill sshd, installs the `hh` alias, and runs the Phase-0 preflight.
#
# Idempotent: safe to re-run. Env: HH_ROOT (default ~/hh-mobile).
set -uo pipefail
ROOT="${HH_ROOT:-$HOME/hh-mobile}"
BASHRC="$HOME/.bashrc"
ok(){ printf ' \033[32m✓\033[0m %s\n' "$*"; }
warn(){ printf ' \033[33m!\033[0m %s\n' "$*"; }
step(){ printf '\n\033[1m== %s ==\033[0m\n' "$*"; }
[ -d "$ROOT" ] || { echo "hh-mobile tree not found at $ROOT — sync it first:"; \
echo " (laptop) tar czf - cmd_chat scripts requirements-operator.txt | \\"; \
echo " ssh -i ~/.ssh/phone-deploy -p 8022 u0_a203@100.95.202.68 'mkdir -p ~/hh-mobile && tar xzf - -C ~/hh-mobile'"; \
exit 1; }
step "Termux packages"
# python-cryptography from the repo avoids compiling the rust cryptography wheel
for p in python tmux git python-cryptography openssh; do
if dpkg -s "$p" >/dev/null 2>&1 || pkg list-installed 2>/dev/null | grep -q "^$p/"; then
ok "$p present"
else
warn "installing $p"; yes | pkg install "$p" >/dev/null 2>&1 && ok "$p installed" || warn "$p install FAILED (continuing)"
fi
done
step "Python operator deps (pure/wheeled — no srp C-ext)"
_py_has(){ python -c "import $1" >/dev/null 2>&1; }
if _py_has requests && _py_has rich && _py_has websockets; then
ok "requests rich websockets importable"
else
warn "installing requests rich websockets…"
pip install --quiet requests rich websockets && ok "pip deps installed" || warn "pip install had errors"
fi
if python -c "from cryptography.fernet import Fernet; Fernet(Fernet.generate_key())" >/dev/null 2>&1; then
ok "cryptography (Fernet) importable"
else
warn "cryptography import FAILED — run: pkg install python-cryptography"
fi
step "Wake-lock (keep Termux/sshd alive when backgrounded)"
if command -v termux-wake-lock >/dev/null 2>&1; then
termux-wake-lock && ok "wake-lock held" || warn "wake-lock failed"
else
warn "termux-wake-lock not found (install Termux:API for it) — Android may kill sshd"
fi
step "hh launcher alias"
if grep -q "alias hh=" "$BASHRC" 2>/dev/null; then
ok "alias already in $BASHRC"
else
printf "\n# hack-house mobile launcher\nalias hh='bash \"%s/scripts/hh\"'\n" "$ROOT" >> "$BASHRC"
ok "added 'hh' alias to $BASHRC (run: source $BASHRC)"
fi
step "Phase-0 preflight"
if [ -f "$ROOT/scripts/termux-preflight.py" ]; then
python "$ROOT/scripts/termux-preflight.py" || warn "preflight reported issues (see above)"
else
warn "scripts/termux-preflight.py not in the synced tree — skipped"
fi
step "Next steps"
cat <<EOF
source $BASHRC # activate the 'hh' alias now
hh host # host a room on this phone (:8799, password hh-mobile)
hh web # mobile web console (:8790)
hh status # what's running
See docs/mobile-quickstart.md for the full grammar.
EOF