phase: 01_keyboard_kiosk_control
Build and Push Containers / test (push) Successful in 35s
Build and Push Containers / build-and-push-app (push) Successful in 10s

**Phase 01 final verification pass — complete, 100% green**

- Verified all 4 tasks done (files in `complete/`); implementation review: key router in `watch.js`, share-page router, CSS focus/selection affordances, `?` overlay, pointer-free E2E suite — all sound.
- Gates: `ruff check` + `ruff format --check` ✅ · `pyright` 0 errors ✅ · `uv run pytest` → 223 passed, 2 skipped (realdisplay), 1 pre-existing FastAPI deprecation warning · `MIRROR_REALDISPLAY=1 pytest -m realdisplay` → 2 passed ✅ · `pytest -m e2e` → 51 passed (incl. `test_keyboard_wall.py`, which a meta-test keeps pointer-free) · `node --check` on all static JS ✅.
- Completion criteria: all 6 ✅ (j/k+Enter, f/g/n/p/1–9/m/?/Esc keyboard-only E2E; no hover-only controls via CSS guard + focus-ring E2E; `#name` text-safe; e2e/realdisplay green; key map documented in README "Kiosk client" and `docs/kiosk-silverblue.md`).
- README fixed: added missing env vars `MIRROR_MAX_BITRATE`, `MIRROR_PING_INTERVAL`, `DEBUGPY_WAIT` to the config table; added the one-time `rpm-ostree` layering note before the kiosk install snippet.
- AGENTS.md fixed: removed stale "roadmap is intentionally empty" parenthetical (3 phases pending); coverage ~94% → ~95%. No content added.
- **Unresolved, needs your call:** README/SECURITY.md say `mirror.reeseapps.com`; `docs/kiosk-silverblue.md` (reference-client naming table with real IPs) says `mirror.reeselink.com`. I couldn't verify which is the live deployment domain, so I changed neither — say the word and I'll unify.
- Next pending phase: `02_sharp_capture`.
This commit is contained in:
2026-11-01 20:53:28 -05:00
parent f3de5b70ff
commit 1e816da5a8
39 changed files with 1726 additions and 31 deletions
+26
View File
@@ -91,6 +91,32 @@ sudo pkill -u kiosk firefox # loop notices within 5s and relaunches
---
## Operating the wall: keys
The whole wall works from a keyboard — and the box needs no keyboard attached
to be operated *or* debugged: everything about it is checkable over SSH (see
[Verifying a kiosk you cannot see](#verifying-a-kiosk-you-cannot-see)). The keys
are there when one is plugged in. On `/watch`:
| Key | Action |
|---|---|
| `j` / `↓` · `k` / `↑` | select the next / previous mirror (wraps) |
| `Enter` / `f` | stage the selected mirror fullscreen (`f` re-enters fullscreen) |
| `g` | back to the wall |
| `n` / `p` | stage the next / previous mirror |
| `1`–`9` | stage the Nth mirror |
| `m` | mute / unmute the staged mirror |
| `?` | show / hide the key list on screen |
| `Esc` | close the key list, then leave the stage |
On `/mirror`: `s` starts a share, `x` stops one, `Esc` stops while live. Keys
with `Ctrl`/`Cmd`/`Alt` are never intercepted, and a key typed in the
display-name field is text, not a command. `?` is the only key that needs
Shift, and it is matched on the character itself, so on a layout where `?` is a
dead key the list is not reachable — keep this table to hand.
---
## Why each piece is where it is
**Auto-login — `/etc/gdm/custom.conf`**