Refactor journal message types to use flatter, more intuitive names:
- `narrative` becomes `chat`
- `article.reveal` becomes `reveal`
- `roll.request`/`roll.result` becomes a single `roll` type
Implement client-side dice roll resolution for GMs. When a GM uses
the `/roll` command, the result is now calculated locally using
`resolveRollPayload` before being sent to the stream, rather than
requesting a roll from the server.
Introduce 'gm', 'player', and 'observer' roles to the journal system.
This includes:
- Restricting command usage and completions to the GM role.
- Implementing role-based message emission permissions.
- Adding a player list and role indicators in the UI.
- Persisting the user's role in localStorage.
- Updating the connection logic to include the role in the client ID.
Introduce a complete set of journal components including:
- JournalPanel: main container with mobile/desktop support
- ConnectionBar: MQTT connection and session management
- StreamView and StreamMessage: message log and individual message cards
- ComposePanel: message composition with type selection
- DynamicForm: recursive form generator based on Zod schemas