- Add HomeNodeView model to city-service
- Update get_public_citizens and get_public_citizen_by_slug to JOIN node_cache
- Add HomeNode interface to frontend types
- Display node badge on citizen cards
- Show full home_node info on citizen profile page
- Add migration 013_city_map_coordinates.sql with map coordinates, zones, and agents table
- Add /city/map API endpoint in city-service
- Add /city/agents and /city/agents/online endpoints
- Extend presence aggregator to include agents[] in snapshot
- Add AgentsSource for fetching agent data from DB
- Create CityMap component with interactive room tiles
- Add useCityMap hook for fetching map data
- Update useGlobalPresence to include agents
- Add map/list view toggle on /city page
- Add agent badges to room cards and map tiles
- matrix-gateway: POST /internal/matrix/presence/online endpoint
- usePresenceHeartbeat hook with activity tracking
- Auto away after 5 min inactivity
- Offline on page close/visibility change
- Integrated in MatrixChatRoom component
- matrix-presence-aggregator v2 with SSE endpoint
- Created @presence_daemon Matrix user
- SSE proxy in Next.js /api/presence/stream
- Updated frontend to use SSE instead of WebSocket
- Real-time city online count and room presence
- MATRIX_PRESENCE_TYPING_SPEC.md documentation
- MatrixRestClient: sync-loop with presence+typing events
- MatrixChatRoom: onlineUsers and typingUsers state
- UI: Show N online in header
- UI: Typing indicator with animation
- ChatInput: onTyping callback support
- matrix_provisioning.py: Create Matrix users via Synapse admin API
- Auto-create Matrix account when user registers in DAARION
- Return matrix_user_id in registration response
- WebSocket chat client for city rooms
- Chat UI components (ChatMessage, ChatInput, ChatRoom)
- Agent Console with agent list and invoke functionality
- Governance/DAO page with proposals and voting
- Updated navigation with new routes
- Extended API client for agents and microdao
- Commented out early 'if not update.message' validation at line 723
- This was preventing photo and voice messages from being processed
- process_photo() and process_voice() functions are already implemented
- Now photo/voice updates can reach multimodal handlers before text validation
- Fixes issue where bots showed placeholder messages instead of processing media