ws: SSL_connect on the non-blocking socket now polls WANT_READ/WANT_WRITE
with a deadline (previously it would fail the very first handshake);
handshake response read in chunks so the 5s deadline can't spuriously
trip; ws_send_text errors on oversized frames instead of silently
truncating; added ws_send_pong for RFC6455 server pings.
discord: heartbeat ack tracking -> reconnect on 2x-interval silence;
handle op 7 (reconnect) and op 9 (invalid session, clears session_id);
parse the sequence from the correct "s" field (was "seq", never
matched, heartbeat always sent d:0); READY captures session_id for
RESUME; reconnect now RESUMEs (op 6) when a session exists and falls
back to IDENTIFY on invalid-session; party size now emitted in the
activity; dropped the unused 'intent' arg; zeroed gateway-fetch buffer.
main: use config presence_state (was hardcoded); reset last_name after
reconnect so the current game is re-pushed immediately.
cfg: clamp poll_interval_s to [5,300]; atomic config save (tmp+rename).
log: seconds in timestamps; rotate log at 512 KB.
jsonlite: jl_obj_get/jl_arr_at return non-const (fixes const-drop
warnings); stringify emits proper "null" for missing pair values.
detect: trim whitespace around app.xml title; drop per-poll log spam.