- ChatScreen: restructure to Box overlay layout so only input area
rises with IME, messages stay fixed. Add opaque background to input
area. Use reverseLayout with newest-first animation order.
- OverlayContent: remove all manual IME detection — system forces
adjust=pan on VoiceInteractionSession windows, so manual padding
caused double offset. Let system handle IME naturally.
- ChatRepositoryImpl: add messageRemovals flow to clean up wrapping
stream_end/response when review/multi_message items arrive later.
Track lastResponseId in both stream_end and response handlers.
- ChatViewModel/OverlayViewModel: fix dedup to check by message ID
only. Sort descending (newest first). Observe messageRemovals.
- NavGraph: keep all tabs composed with graphicsLayer alpha toggle —
prevents ChatScreen destruction and re-render on tab switch.
- CyreneVoiceInteractionSession: defer configureWindow via post()
to override system softInputMode flags.
- AndroidManifest: set windowSoftInputMode=adjustNothing on main
activity.
- Add WebSocketKeepAliveService for background connection persistence.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
R8 was stripping Android components (services, application),
Room entities, Koin modules, and ViewModels — causing crash
when VoiceInteractionService was invoked via power button.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>