Model/scripts/hyde/start_viewer.sh
Jun-te Kim 2f0eb49eee Checkpoint: UPRN 10093116543 Elmhurst build + devcontainer VNC/Playwright + perms
- Add SAP-accuracy sample for uprn_10093116543 (epc.json, elmhurst_inputs.md,
  summary/worksheet PDFs)
- Persist hyde viewer stack (xvfb/fluxbox/x11vnc/novnc/websockify) and Playwright
  chromium in the backend devcontainer; forward noVNC 6080
- Broaden .claude/settings.local.json allowlist (display/python/grep/tail)
- In-progress campaign mapper/cert_to_inputs work carried from prior cert

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 15:21:56 +00:00

89 lines
3 KiB
Bash
Executable file

#!/usr/bin/env bash
# Stand up a *viewable* desktop inside the dev container so you can see and
# click the headed Elmhurst browser. Pipeline:
#
# Xvfb (:99 virtual screen) -> fluxbox (window manager)
# -> x11vnc (exposes :99 over VNC on 5900)
# -> websockify/noVNC (serves VNC in a browser tab on 6080)
#
# Then: forward port 6080 (VS Code does this automatically), open it, and run
# Playwright with DISPLAY=:99 so the browser appears on this desktop.
#
# bash scripts/hyde/start_viewer.sh # start it
# bash scripts/hyde/start_viewer.sh stop # tear it down
#
# Idempotent: re-running won't stack duplicate servers.
set -euo pipefail
DISPLAY_NUM=":99"
SCREEN="1600x1000x24"
VNC_PORT=5900
WEB_PORT=6080
RUN_DIR="/tmp/hyde-viewer"
mkdir -p "$RUN_DIR"
_pids() { pgrep -f "$1" 2>/dev/null || true; }
stop() {
echo "Stopping viewer..."
for pat in "websockify.*$WEB_PORT" "x11vnc.*$DISPLAY_NUM" "fluxbox" "Xvfb $DISPLAY_NUM"; do
for pid in $(_pids "$pat"); do kill "$pid" 2>/dev/null || true; done
done
rm -f "/tmp/.X${DISPLAY_NUM#:}-lock" 2>/dev/null || true
echo "Stopped."
}
start() {
# Xvfb — the virtual screen everything draws into.
if [ -z "$(_pids "Xvfb $DISPLAY_NUM")" ]; then
Xvfb "$DISPLAY_NUM" -screen 0 "$SCREEN" -ac >"$RUN_DIR/xvfb.log" 2>&1 &
sleep 1
echo "Xvfb up on $DISPLAY_NUM ($SCREEN)"
else
echo "Xvfb already running on $DISPLAY_NUM"
fi
# fluxbox — a window manager so the browser window is movable/resizable.
if [ -z "$(_pids "fluxbox")" ]; then
DISPLAY="$DISPLAY_NUM" fluxbox >"$RUN_DIR/fluxbox.log" 2>&1 &
sleep 1
echo "fluxbox window manager up"
fi
# x11vnc — exposes the screen over VNC. -forever keeps it alive across
# client reconnects; -nopw is fine because the port is only reachable
# through the container's forwarded port, not the public internet.
if [ -z "$(_pids "x11vnc.*$DISPLAY_NUM")" ]; then
x11vnc -display "$DISPLAY_NUM" -rfbport "$VNC_PORT" -forever -shared \
-nopw -quiet -bg -o "$RUN_DIR/x11vnc.log"
echo "x11vnc up on VNC port $VNC_PORT"
else
echo "x11vnc already running"
fi
# noVNC/websockify — serves the VNC stream as a web page on WEB_PORT.
if [ -z "$(_pids "websockify.*$WEB_PORT")" ]; then
websockify --web=/usr/share/novnc "$WEB_PORT" "localhost:$VNC_PORT" \
>"$RUN_DIR/websockify.log" 2>&1 &
sleep 1
echo "noVNC up on web port $WEB_PORT"
fi
cat <<EOF
Desktop ready.
1. Open the forwarded port $WEB_PORT in your browser:
http://localhost:$WEB_PORT/vnc.html?autoconnect=1&resize=remote
(In VS Code: PORTS tab -> forward $WEB_PORT -> open in browser.)
2. Run the Playwright login pointing at this display:
DISPLAY=$DISPLAY_NUM python scripts/hyde/elmhurst_session.py login --url <elmhurst-url>
The browser window will appear on the desktop you opened in step 1.
EOF
}
case "${1:-start}" in
start) start ;;
stop) stop ;;
restart) stop; start ;;
*) echo "usage: $0 [start|stop|restart]"; exit 2 ;;
esac