docs(mobile): operator quickstart — hh launcher, direnv, web console, capture, skills
User-facing how-to distinct from the design spec: the port-probe reachability gate, one-time Termux setup + tar-over-ssh sync, the hh launcher grammar, per-directory direnv auto-host, the mobile web console, phone-capture.sh routes (non-root file/term/webshot vs ADB shot/screen), and the Fairphone skill ship-list. Linked from termux-operator.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
# hack-house on the phone — mobile quickstart
|
||||
|
||||
Run and drive a hack-house room from the **Fairphone-6** (Termux, Android). This
|
||||
is the *operator's* how-to; the design rationale lives in
|
||||
[`termux-operator.md`](termux-operator.md).
|
||||
|
||||
Two devices are in play:
|
||||
|
||||
- **the phone** — Termux, `aarch64`, Python 3.13, reached over Tailscale as
|
||||
`100.95.202.68` (sshd on **:8022**, user `u0_a203`). Hosts/joins rooms.
|
||||
- **the laptop / dev-box** — pulls captures off the phone, joins phone-hosted
|
||||
rooms, and does any chromium/Whisper-heavy work the phone can't.
|
||||
|
||||
> **Reachability first.** Android kills backgrounded Termux, taking `sshd` with
|
||||
> it — and `tailscale status` still shows the phone `active`. Always probe the
|
||||
> **port**, not the tailnet:
|
||||
> ```bash
|
||||
> timeout 8 bash -c 'cat </dev/null >/dev/tcp/100.95.202.68/8022' \
|
||||
> && echo REACHABLE || echo OFFLINE
|
||||
> ```
|
||||
> If OFFLINE the fix is on-device: wake the phone, open Termux, run
|
||||
> `termux-wake-lock` and start `sshd`. Don't hammer a dead port.
|
||||
|
||||
---
|
||||
|
||||
## 1. One-time on-device setup
|
||||
|
||||
```bash
|
||||
# in Termux, on the phone
|
||||
pkg install python tmux git python-cryptography # cryptography avoids a rust build
|
||||
pip install requests rich websockets # skip `srp` — the pure shim covers it
|
||||
termux-wake-lock # keep Termux/sshd alive when backgrounded
|
||||
```
|
||||
|
||||
Sync the repo onto the phone (tar-over-ssh from the laptop — no gitea clone
|
||||
needed if the branch is unpushed):
|
||||
|
||||
```bash
|
||||
# from the laptop, in this repo
|
||||
tar czf - cmd_chat scripts requirements-operator.txt \
|
||||
| ssh -i ~/.ssh/phone-deploy -p 8022 u0_a203@100.95.202.68 'mkdir -p ~/hh-mobile && tar xzf - -C ~/hh-mobile'
|
||||
```
|
||||
|
||||
Add the launcher alias to `~/.bashrc` on the phone:
|
||||
|
||||
```bash
|
||||
alias hh='bash "$HOME/hh-mobile/scripts/hh"'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. The `hh` launcher
|
||||
|
||||
Everything runs in a persistent tmux session named `hh`, so it survives an SSH
|
||||
drop. `HH_PY` defaults to `python`; override any config via env (see the header
|
||||
of `scripts/hh`).
|
||||
|
||||
```bash
|
||||
hh host [NAME] [PORT] # host a room ON THE PHONE (default :8799)
|
||||
hh join HOST PORT [NAME] # join an existing room as operator
|
||||
hh web [PORT] # serve the mobile web console (default :8790)
|
||||
hh op <args...> # passthrough to `python -m cmd_chat.operator`
|
||||
hh status # what's running + listening (curl health per room)
|
||||
hh stop [all|host [PORT]|web [PORT]|join]
|
||||
```
|
||||
|
||||
Room windows are **port-scoped** (`host-8799`, `web-8790`), so several rooms
|
||||
coexist — one per directory when paired with direnv below.
|
||||
|
||||
```bash
|
||||
hh host myroom 8799 # → hosting on 0.0.0.0:8799 (password: hh-mobile)
|
||||
hh status # host :8799 UP (health json) · operator daemons
|
||||
hh stop host 8799 # tear down just that room
|
||||
```
|
||||
|
||||
Config env (all optional): `HH_PASSWORD` (hh-mobile), `HH_PORT` (8799),
|
||||
`HH_WEB_PORT` (8790), `HH_NAME` (dir basename), `HH_BIND` (0.0.0.0), `HH_TLS`
|
||||
(1 → keep TLS; default drops it with `--no-tls`).
|
||||
|
||||
## 3. Auto-host a room per directory (direnv)
|
||||
|
||||
Drop an `.envrc` in any project dir so `cd`-ing in auto-hosts a room named after
|
||||
the directory:
|
||||
|
||||
```bash
|
||||
# .envrc
|
||||
export HH_PORT=8801 # optional; override before sourcing
|
||||
source "$HOME/hh-mobile/scripts/hh-direnv.sh"
|
||||
```
|
||||
|
||||
`direnv allow`, then every `cd` in idempotently ensures the room is up (the
|
||||
launcher no-ops if the window already exists). Disable hosting but keep the env
|
||||
with `export HH_AUTOHOST=0`.
|
||||
|
||||
## 4. Mobile web console
|
||||
|
||||
`hh web` serves a stdlib web UI in front of the operator daemon — Terminal + Chat
|
||||
tabs, a quick-keys row (Enter/^C/Esc/Tab/↑/↓/clear/^D), and a command box.
|
||||
|
||||
- On the phone browser: `http://127.0.0.1:8790`
|
||||
- From the laptop: `http://100.95.202.68:8790`
|
||||
|
||||
It's **read-only** until a room owner runs `/grant <name>`; until then keys/exec
|
||||
are inert by design.
|
||||
|
||||
---
|
||||
|
||||
## 5. Capture & share from the phone (`scripts/phone-capture.sh`)
|
||||
|
||||
Runs on the **laptop**; it SSHes into the phone and pulls content back. Add
|
||||
`--tg [target]` to any command to also ship the artifact to Telegram.
|
||||
|
||||
```bash
|
||||
scripts/phone-capture.sh file <remote> [local] # pull a file/dir (tar over ssh)
|
||||
scripts/phone-capture.sh term [tmux-session] # capture tmux pane text (default: hh)
|
||||
scripts/phone-capture.sh webshot <url> [png] # screenshot a URL via headless chromium
|
||||
scripts/phone-capture.sh shot [png] # device screenshot (needs ADB)
|
||||
scripts/phone-capture.sh screen [secs] [mp4] # device screen record (needs ADB)
|
||||
```
|
||||
|
||||
**Non-root routes** (`file`, `term`, `webshot`) work straight from the Termux app
|
||||
uid. Example — grab the live web console as a PNG:
|
||||
|
||||
```bash
|
||||
scripts/phone-capture.sh webshot 'http://100.95.202.68:8790/' --tg
|
||||
```
|
||||
|
||||
**Screen capture** (`shot`/`screen`) can't reach SurfaceFlinger from an app uid,
|
||||
so it needs ADB over **Wireless Debugging** (Settings → System → Developer
|
||||
options). If ADB isn't connected the script prints the one-time pairing steps.
|
||||
|
||||
Env overrides: `PHONE_IP`, `PHONE_PORT`, `PHONE_USER`, `PHONE_KEY`; captures land
|
||||
in `~/coding/_data/phone-captures/`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Which Claude skills to ship to the phone
|
||||
|
||||
Lean, self-contained skills that earn their place on a phone (bash/curl/ssh, no
|
||||
chromium, no build step):
|
||||
|
||||
**Ship now:** `hh-operator` · `tg-send`/`tg-direct` (ship captures out) ·
|
||||
`transcribe` (offloads to laptop Whisper over SSH — ideal for a phone) ·
|
||||
`dns-toolkit` · `news-intel` · `session-audit` · `project-map` · `site-audit`.
|
||||
|
||||
**Tether, don't relocate:** `screenshot` (already covered by
|
||||
`phone-capture.sh webshot`), `web-video-grab` (yt-dlp mode only — the Playwright
|
||||
path needs chromium), `youtube-research`/`vault-*`/`imagegen` (laptop-heavy).
|
||||
|
||||
**Skip:** anything GPU/vision, local-infra (gitea-admin, Nuclei/Suricata
|
||||
digests), creds-on-laptop (IMAP/gopass email), or OAO business skills.
|
||||
|
||||
Leanest starter kit: `hh-operator + tg-send + transcribe + dns-toolkit +
|
||||
session-audit + news-intel`.
|
||||
Reference in New Issue
Block a user