5.4 KiB
UI follow-up — 2026-10-23
Scope: targeted improvements on the legacy layout and light functional testing. No redesign, no load test, no legacy credentials or game-host traffic. No backend HTTP contracts or forwarding modules changed.
Layout and readability
| Before | After |
|---|---|
| Bootstrap reset placed native dialog at x=0,y=0. | web/app.css: explicit auto margin/inset; centered, bounded, scrollable dialogs. Reproduced before and measured after in browser. |
| Header controls squeezed selected-team IP and replica count onto extra lines. | Header uses a full-width second row; name/IP ellipsis and stable replica suffix with full tooltip. |
| Bright native number spinners and shifting digit widths. | Dark color scheme, spinner removal, numeric input mode/step and tabular counters. |
| Adding toolbar actions could crowd the mobile title. | Compact action spacing and small-screen title size, preserving original columns. |
Input and operator workflow
| Before | After |
|---|---|
| Reopening add-proxy cleared its draft. | Draft retained until successful creation or page reload. |
| Rejected custom IP could disappear on next snapshot. | Local dirty draft survives blur and snapshots; inline IPv4/IPv6 validation, Enter saves/retries, Escape restores saved value. |
| Changing direct IP discarded all replicas. | Preserve replicas; backend removes only overlap with the new primary. |
| Whitespace-only names passed required validation. | Trim/validate names before requests; settings reset stale custom-validity messages. |
| Team PUT was only reachable through API. | Compact Teams dialog adds/renames teams; existing address is read-only and hidden state preserved. |
| Renamed team retained the old primary-control label. | Accessible name and tooltip update with team name. |
| No in-panel configuration/scoreboard guidance. | Compact help dialog with live existing scoreboard state, TOML/ForcAD example and route semantics. |
| Non-JSON API failure detail was discarded. | Show bounded plain-text errors when returned by the server. |
| Demo wrapper deleted config/state after each exit. | Optional persistent --data-dir, existing config never overwritten; --port-offset isolates new test fixtures. Echo cleanup tolerates reset peers. |
Fresh verification
- Native
cargo fmt --check,cargo clippy --all-targets --locked -- -D warnings,cargo test --all-targets --locked: pass, 40 tests. Repeated after final frontend edits;node --check web/app.jsandgit diff --checkpass. - Orb Ubuntu amd64: 41 tests including Linux loopback alias behavior; release build passes. Linux tests preceded the last frontend-only label/layout/validation changes; final Linux release embeds those final assets. No Linux-specific code changed.
- macOS arm64 release built after final assets. Both local
dist/artifacts have refreshed and verified SHA256SUMS. Initial checksum command used wrong cwd; rerun from dist verified both files. - Browser Use on isolated fixture
127.0.0.1:16800: login, add IPv6 proxy, port range rejection, draft cancel/reopen, invalid IP via real keyboard, inline error retention through refresh, Escape restoration, valid IPv4 save, team create and rename, read-only existing address, port/policy editing, start, primary promotion retaining former primary as replica, robot toggle and logout. - Created test proxy deletion confirmed through native Chrome after Browser Use
could not prepare popup headers for
window.confirm; persisted state and a fresh browser tab confirmed the proxy was gone. This was a browser-control issue. SIGSTOPonly on isolated fixture: five-second watchdog disables mutations and shows stale warning;SIGCONTrestores live state/buttons. Live demo unaffected.- Persistence: isolated fixture restart preserved created service/team and rename.
- Actual 390×844 CSS viewport measured (accounting for existing browser 80% zoom): add-dialog rectangle x≈19,y≈203.55,w≈351.99,h≈436.64; no page horizontal overflow. Long help dialog bounded at y=20,h≈803.75 with scrolling. Override cleared.
- Byte-exact 256 KiB echo with TCP half-close; replica bytes also 262144, no connect/I/O/replica errors or replica disconnections. This is a functional check, not a speed benchmark.
- Console samples contained unrelated extension
content.jserrors; no application JavaScript exception observed. Does not establish absence of every possible bug.
Live demo and artifacts
GUI-session launchd job local.codex.mirror-tool-demo runs current macOS release.
Plist is ignored test-results/mirror-ui-demo.plist, outside LaunchAgents; not an
installed login service. Existing temporary config/state were copied before stopping
old fixture; live authenticated snapshot confirmed identical teams/service settings.
Current config data/demo/mirror.toml, state data/demo/state.json, both ignored.
Panel http://127.0.0.1:16700, Echo listener 18081, echo upstreams 18082 (IPv4/IPv6).
User's primary B / replica A / enabled state preserved. A fresh 21504-byte echo passed
on updated demo, plus readiness, embedded assets and actual GUI verification.
Ignored screenshot evidence: test-results/ui-polish-final.png,
test-results/ui-polish-mobile.png. Isolated test fixture stopped. The user's Zen
window was not reloaded; updated demo is open in a separate Chrome tab. Instructions
are in docs/configuration.md and linked from README. Real ForcAD tournament access,
load/soak tests and network-failure losslessness are not claimed.