Presentation stays separate from device logic
The desktop application follows this dependency direction:
QML Presentation → C++ ViewModel → Application Services → Core Services → Domain → Infrastructure
QML binds typed observable state and emits commands. ADB and scrcpy processes are owned by C++ services, never by presentation code. Exceptions do not cross module, process, plugin or FFI boundaries.
Mirroring lifecycle
MirrorViewModel validates user settings and delegates to MirrorService. The service supervises
one isolated scrcpy child process per device serial, publishes lifecycle events and performs bounded
recovery. Failures retain a cause, solution and technical detail instead of exposing raw process
output as the user-facing message.