Implements issue #1093: Timmy reads Bannerlord game state via the GABS
TCP JSON-RPC bridge and journals it to memory/bannerlord/journal.md.
Changes:
- src/config.py: add GABS settings (host, port, timeout, poll_interval,
journal_path) — all off by default (gabs_enabled=False)
- src/integrations/bannerlord/gabs_client.py: GabsClient — synchronous
TCP JSON-RPC 2.0 client with graceful GabsError handling; exposes
get_game_state(), get_player(), get_player_party(), list_kingdoms()
- src/integrations/bannerlord/observer.py: BannerlordObserver — async
observe() loop that polls GABS every poll_interval seconds and formats
game state into structured Markdown journal entries; degrades gracefully
when GABS is unreachable (logs warning, no crash)
- tests/integrations/test_gabs_observer.py: 21 unit tests (all offline,
sockets mocked) covering TCP failure, RPC errors, partial snapshots,
journal creation, and the observe(days=N) stop condition
Fixes#1093
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>