JesterContent fields version, fen, and history were omitted from
serialized JSON because kotlinx.serialization skips default values.
Jester's isStartGameEvent checks arrayEquals(json.history, []) which
fails when the field is absent (undefined !== []).
Added @EncodeDefault to version, fen, and history so they are always
included in the JSON output regardless of value.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jester.nyo.dev uses offchain.pub as one of its relays. Adding it gives
us 2 shared relays (relay.damus.io + offchain.pub) instead of 1,
improving challenge visibility between Amethyst and Jester clients.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ChessEngine.makeMove() now normalizes SAN notation before passing to
chesslib, fixing games against jester.nyo.dev and other clients that
use different notation:
- Castling: 0-0 → O-O, 0-0-0 → O-O-O (zeros to letters)
- Annotations: strips !, ?, !!, ??, !?, ?! suffixes
Previously, chesslib rejected 0-0/0-0-0 causing ChessStateReconstructor
to mark games as desynced and skip remaining moves. Games appeared
permanently stuck, even after app restart.
Also fixes discoverUserGames() silently dropping games classified as
spectator — now adds them to spectatingGames instead.
23 new interop tests covering SAN variants, reconstruction, spectator
detection, and missing start event handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updated CHANGELOG for release v1.06.0, detailing new features, improvements, and removals including support for NIP-85 Polls, custom NIP-40 Expirations, and various UI enhancements.
Replace the requireAuth: Boolean parameter in NostrServer with a
pluggable AuthPolicy interface. Each policy has trigger points for
EVENT (acceptEvent), REQ (acceptReq with filter rewriting), COUNT
(acceptCount), and live event delivery (canSendToSession).
Built-in policies: OpenPolicy (allow all) and RequireAuthPolicy
(require auth for all commands, matching the previous behavior).
https://claude.ai/code/session_017vdjbdxdYK1oJMH66koVZE