Previously only wrote dirty keys, causing data loss when multiple
modules wrote concurrently. Now writes full state atomically using
temp file + rename pattern.
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, tokens with expires_in were recalculated as Date.now() +
3600s on each load, ignoring the actual JWT expiry. Now decodes the
JWT's exp claim to get true expiry and resaves file with expires_at.
Co-Authored-By: Claude <noreply@anthropic.com>
- HEAD request to game-patches.hytale.com for content-length
- Track lastPatchId in state to calculate patch delta
- Display formatted size (~55.4 MiB) in update notifications
Co-Authored-By: Claude <noreply@anthropic.com>
Fetch replied message content/author when Discord message type is REPLY,
display as Telegram blockquote with link to original.
Co-Authored-By: Claude <noreply@anthropic.com>