{ "version": "v0.7", "date": "2026-06-08", "title": "UI Layout System", "layout": "default", "messageId": null, "sections": [ { "type": "new", "label": "New Features", "emoji": "✨", "items": [ { "text": "Poll layout system — multiple display styles, switchable via `/tg-config poll set-layout`", "emojiKey": null }, { "text": "`default` layout — standard vertical nation fields", "emojiKey": null }, { "text": "`side-by-side` layout — nations displayed inline, auto-stacks when >5 players per nation", "emojiKey": null }, { "text": "Layout persists across bot restarts", "emojiKey": null } ] }, { "type": "improvement", "label": "Improvements", "emoji": "⚡", "items": [ { "text": "Voting Yes and No now run in parallel — faster poll embed updates", "emojiKey": null }, { "text": "Autocomplete filtered by nation for Bringer set command", "emojiKey": null }, { "text": "Character class now carries full name and emoji — `Force Blader`, `Wizard`, etc.", "emojiKey": null } ] }, { "type": "technical", "label": "Under the Hood", "emoji": "🔩", "items": [ { "text": "`BaseLayout` — shared functions inherited by all layouts, override only what differs", "emojiKey": null }, { "text": "Layout auto-discovery — drop a file in `layouts/` and it registers automatically", "emojiKey": null }, { "text": "`Character` type now carries `ownerKey` and full `CharacterClass` object", "emojiKey": null }, { "text": "`SerializableCharacter` — clean JSON serialization boundary, runtime uses rich types", "emojiKey": null }, { "text": "`Nation` converted to string enum — serializes cleanly, exhaustiveness checked by TypeScript", "emojiKey": null } ] } ], "examples": [ { "caption": "side-by-side layout — nations displayed inline", "type": "poll", "layout": "side-by-side", "file": "examples/poll-side-by-side.json" } ] }