apps/server/src/device/DeviceHubProxy.test.ts | 26 ++ apps/server/src/device/DeviceHubProxy.ts | 1 + apps/server/src/device/DeviceToolchain.ts | 2 +- apps/web/src/components/device/DeviceControlsRail.tsx | 7 +- apps/web/src/components/device/DeviceDuoControls.tsx | 75 ++++ apps/web/src/components/device/DeviceDuoGlyph.tsx | 43 ++ apps/web/src/components/device/DeviceDuoViewport.tsx | 205 ++++++++++ apps/web/src/components/device/DeviceStreamView.tsx | 83 +++- apps/web/src/components/device/deviceModels.ts | 2 + apps/web/src/components/device/models/iphone-duo.glb | Bin 0 -> 3097724 bytes apps/web/src/components/device/models/sources.json | 10 +- docs/user/devices.md | 6 + packages/client-runtime/package.json | 8 + packages/client-runtime/src/device/duoControl.test.ts | 109 +++++ packages/client-runtime/src/device/duoControl.ts | 113 +++++ packages/client-runtime/src/device/duoScene.test.ts | 108 +++++ packages/client-runtime/src/device/duoScene.ts | 244 +++++++++++ packages/client-runtime/src/device/duoSnap.test.ts | 54 +++ packages/client-runtime/src/device/duoSnap.ts | 86 ++++ packages/client-runtime/src/device/duoStream.test.ts | 285 +++++++++++++ packages/client-runtime/src/device/duoViewer.test.ts | 703 ++++++++++++++++++++++++++++++++ packages/client-runtime/src/device/duoViewer.ts | 566 +++++++++++++++++++++++++ packages/client-runtime/src/device/model.test.ts | 1 + packages/client-runtime/src/device/model.ts | 3 +- packages/client-runtime/src/device/stream.ts | 255 +++++++++++- 25 files changed, 2951 insertions(+), 44 deletions(-)