* docs: add screenshot drift prevention guide and CI workflow
- Add docs/SCREENSHOT-GUIDE.md with step-by-step instructions for
capturing, optimising, and committing fresh README screenshots
- Add .github/workflows/screenshot-drift.yml that detects UI file
changes in PRs, applies a 'screenshot-drift' label, and posts a
checklist comment reminding contributors to verify screenshots
Addresses: README screenshots may drift as the UI evolves quickly
(setup wizard, health history timeline, and onboarding were added
after the last screenshot refresh on 2026-03-11)
* fix(gateway): resolve Docker connectivity — 404 endpoints, EROFS write, missing OPENCLAW_HOME
Fixes#332, #333
Root causes
-----------
1. nodes/route.ts called non-existent HTTP REST endpoints on the gateway
(/api/presence, /api/devices, /api/rpc). The OpenClaw gateway only
exposes HTTP at /health; all other operations use WebSocket RPC.
2. gateway-runtime.ts attempted fs.writeFileSync on openclaw.json which
fails with EROFS when the container or mount is read-only (docker-compose
uses read_only: true by default).
3. install.sh never wrote the detected OPENCLAW_HOME or Docker host gateway
IP into .env, leaving OPENCLAW_HOME empty after a fresh install.
Fixes
-----
- nodes/route.ts: replace HTTP calls to /api/presence and /api/devices
with gateway /health reachability check + callOpenClawGateway() RPC
(node.list / device.pair.list). When the openclaw CLI is unavailable
inside Docker, the RPC falls back gracefully and returns connected=true
with an empty list rather than a misleading 'Gateway offline' error.
POST device actions likewise use callOpenClawGateway instead of /api/rpc.
- gateway-runtime.ts: catch EROFS / EACCES / EPERM on config write and
emit a warn-level log with a hint, instead of an error. This eliminates
the 'Failed to register MC in gateway config EROFS: read-only file
system' log spam on Docker installs where openclaw.json is read-only.
- install.sh: after generating .env, write the detected OPENCLAW_HOME.
In --docker mode also detect the Docker host IP (host-gateway or bridge
default) and set OPENCLAW_GATEWAY_HOST so the container can reach a
gateway running on the host out of the box.
- docker-compose.yml: add extra_hosts host-gateway so the container can
resolve the Docker host IP; add a commented volume snippet for mounting
the OpenClaw state directory read-only.