@xenon-device-management/xenon 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/README.md +2 -1
  2. package/lib/package.json +3 -4
  3. package/lib/public/assets/{AnnotationOverlay-BmTPCAds.js → AnnotationOverlay-XpewX5nn.js} +1 -1
  4. package/lib/public/assets/{ApiKeyGate-B5eB7f8B.js → ApiKeyGate-BQDv3ZCC.js} +1 -1
  5. package/lib/public/assets/BugReportButton-C7OmS61B.js +10 -0
  6. package/lib/public/assets/{DeviceMosaicView-9DUoZnQi.js → DeviceMosaicView-wl3l2Zlt.js} +1 -1
  7. package/lib/public/assets/{EmptyState-lvyNiXev.js → EmptyState-fPxujqqE.js} +1 -1
  8. package/lib/public/assets/{FieldGroup-BduMPM9K.js → FieldGroup-5bCutWrs.js} +1 -1
  9. package/lib/public/assets/{FilterMenu-BSqX6I94.js → FilterMenu-owsBiDT1.js} +1 -1
  10. package/lib/public/assets/{Menu-Ba5cT7jZ.js → Menu-DFhqzPSt.js} +1 -1
  11. package/lib/public/assets/{Modal-CceoMY7D.js → Modal-Bw-a-E-e.js} +1 -1
  12. package/lib/public/assets/{RecordingPage-6T9dOidc.js → RecordingPage-WtByf5bC.js} +1 -1
  13. package/lib/public/assets/{RecordingsPage-qj6FdZXR.js → RecordingsPage-FpWWFNgT.js} +1 -1
  14. package/lib/public/assets/{SegmentedControl-CSRuZ8TR.js → SegmentedControl-Jzn9c7o8.js} +1 -1
  15. package/lib/public/assets/{SettingCard-Bp1kz4By.js → SettingCard-BR7nOhpT.js} +1 -1
  16. package/lib/public/assets/{Table-LV7zFyZg.js → Table-B_Va3V05.js} +1 -1
  17. package/lib/public/assets/{activity-D17TUloi.js → activity-DxRFWvkN.js} +1 -1
  18. package/lib/public/assets/{ai-settings-qvbhY89P.js → ai-settings-CQf-9_V6.js} +1 -1
  19. package/lib/public/assets/{api-keys-BfpvdG7G.js → api-keys-SoE1Kd7N.js} +1 -1
  20. package/lib/public/assets/{apps-Dbnzd0fW.js → apps-CgGXTlgn.js} +1 -1
  21. package/lib/public/assets/{arrow-left-DD1VjtC7.js → arrow-left-uQ6WIwiC.js} +1 -1
  22. package/lib/public/assets/{arrow-right-D0pnM3ma.js → arrow-right-C9RyfzXS.js} +1 -1
  23. package/lib/public/assets/{arrow-up-right-BIC8JOV6.js → arrow-up-right-DFHi_8yG.js} +1 -1
  24. package/lib/public/assets/{auth-shell-DWHPXSnI.js → auth-shell-Bii1t4qc.js} +2 -2
  25. package/lib/public/assets/{builds-page-ClCNBUv_.js → builds-page-Bnv8Z9hi.js} +1 -1
  26. package/lib/public/assets/{button-xtAhYR-f.js → button-_Y78wXiP.js} +1 -1
  27. package/lib/public/assets/{calendar-CupwJ7Bm.js → calendar-D4MqSOc2.js} +1 -1
  28. package/lib/public/assets/{check-CyuEoKkd.js → check-uGHCXe-L.js} +1 -1
  29. package/lib/public/assets/{chevron-left-DgX-F9xK.js → chevron-left-Dy1OqpzB.js} +1 -1
  30. package/lib/public/assets/{chevron-right-BKJgJnU9.js → chevron-right-BUsldEli.js} +1 -1
  31. package/lib/public/assets/{circle-check-CZdg8mMa.js → circle-check-D3Qq0tKp.js} +1 -1
  32. package/lib/public/assets/{circle-x-CZH6t9z-.js → circle-x-B4IOD1DE.js} +1 -1
  33. package/lib/public/assets/{clock-Cd-t7xpe.js → clock-BfYfzvSg.js} +1 -1
  34. package/lib/public/assets/{copy-C6zerX3I.js → copy-DZwYE5Va.js} +1 -1
  35. package/lib/public/assets/{device-explorer-B1pI6b_M.js → device-explorer-CRG4Utt5.js} +3 -3
  36. package/lib/public/assets/device-explorer-D2AqrrLN.css +1 -0
  37. package/lib/public/assets/{download-x9WP7mcL.js → download-CCDYo_TN.js} +1 -1
  38. package/lib/public/assets/{forgot-password-B0TEH4N-.js → forgot-password-DuLCmVFb.js} +1 -1
  39. package/lib/public/assets/{funnel-Cb40MfFN.js → funnel-CtKNPqzb.js} +1 -1
  40. package/lib/public/assets/{index-BR1wTIPC.js → index-3uxl3o7K.js} +43 -43
  41. package/lib/public/assets/{index-BvH_ekRy.js → index-Zy1Op5C1.js} +1 -1
  42. package/lib/public/assets/{input-DejcCiTI.js → input-CzTWvUXZ.js} +1 -1
  43. package/lib/public/assets/{keycodes-Mavx5iGg.js → keycodes-CI-nYDFM.js} +1 -1
  44. package/lib/public/assets/{layers-BKqYLiHE.js → layers-YZZGFyTX.js} +1 -1
  45. package/lib/public/assets/{lock-LFsFhc17.js → lock-L8tzWgDo.js} +1 -1
  46. package/lib/public/assets/{login-x2pkzt-t.js → login-DBbX-fu8.js} +1 -1
  47. package/lib/public/assets/{maintenance-settings-CYafcoV-.js → maintenance-settings-AJwkOIsE.js} +1 -1
  48. package/lib/public/assets/{monitor-_7_uJ8d9.js → monitor-Di_66F2m.js} +1 -1
  49. package/lib/public/assets/{mouse-pointer-2-BfLuURKN.js → mouse-pointer-2-Cnab2zdg.js} +1 -1
  50. package/lib/public/assets/{network-Z_zBhpsD.js → network-DiSumY-1.js} +1 -1
  51. package/lib/public/assets/{overview-BY5uv08S.js → overview-CwE4gXl5.js} +1 -1
  52. package/lib/public/assets/{page-header-CP2UkykG.js → page-header-CfR4Sm9V.js} +1 -1
  53. package/lib/public/assets/{plus-BTD0dnQ0.js → plus-DOS8P9CQ.js} +1 -1
  54. package/lib/public/assets/{profile-page-BhJZuCS7.js → profile-page-BYpHwQIH.js} +1 -1
  55. package/lib/public/assets/{reset-password-CMN0SO81.js → reset-password-BRVJU_qV.js} +1 -1
  56. package/lib/public/assets/{runbook-page-CBpPX9_5.js → runbook-page-Bi3JvAFZ.js} +1 -1
  57. package/lib/public/assets/{select-Uc9E5pye.js → select-Cqx7pEou.js} +1 -1
  58. package/lib/public/assets/{selector-detail-page-BSyBnRuU.js → selector-detail-page-C0DsncKj.js} +1 -1
  59. package/lib/public/assets/{selector-health-DzqxNkzm.js → selector-health-CAhpdilF.js} +1 -1
  60. package/lib/public/assets/{selector-health-page-CyPLjoD1.js → selector-health-page-CrCVeW2m.js} +1 -1
  61. package/lib/public/assets/{session-detail-page-BZQZN1P-.js → session-detail-page-F_hwYqEt.js} +1 -1
  62. package/lib/public/assets/{settings-CkSWiZq8.js → settings-C-s5pypL.js} +1 -1
  63. package/lib/public/assets/{status-pill-outline-BFYni2qo.js → status-pill-outline-DY5uzv6A.js} +1 -1
  64. package/lib/public/assets/{tablet-BSd-xSZK.js → tablet-Dli7gwyg.js} +1 -1
  65. package/lib/public/assets/{teams-PpoEQz31.js → teams-ui4IhHNC.js} +1 -1
  66. package/lib/public/assets/{trash-2-BorJv5_u.js → trash-2-BV4hSmXJ.js} +1 -1
  67. package/lib/public/assets/{upload-C3i7sAZl.js → upload-DkGy_J-L.js} +1 -1
  68. package/lib/public/assets/{use-password-reset-mode-CeZQ3EsH.js → use-password-reset-mode-BFtMqQOh.js} +1 -1
  69. package/lib/public/assets/{users-Drd7ifJx.js → users-BU0nXIVe.js} +1 -1
  70. package/lib/public/assets/{users-CEJ3fC78.js → users-Nb_rzRmF.js} +1 -1
  71. package/lib/public/assets/{video-off-CNzn6bPE.js → video-off-CUNzD2kH.js} +1 -1
  72. package/lib/public/assets/{webhook-settings-BFqX6QXV.js → webhook-settings-Ca3UFXZe.js} +1 -1
  73. package/lib/public/assets/{zap-4yN8Jdfw.js → zap-B2bH2vKX.js} +1 -1
  74. package/lib/public/index.html +1 -1
  75. package/lib/src/InternalHttpClient.js +5 -1
  76. package/lib/src/XenonCapabilityManager.js +15 -1
  77. package/lib/src/app/appiumBasePath.js +32 -0
  78. package/lib/src/app/index.js +12 -0
  79. package/lib/src/app/insertBeforeRoutes.js +24 -4
  80. package/lib/src/app/registerCommandAuth.js +152 -33
  81. package/lib/src/app/routers/control.js +11 -104
  82. package/lib/src/app/routers/grid.js +28 -8
  83. package/lib/src/app/routers/nodePhoneControl.js +301 -0
  84. package/lib/src/app/ws/h264StreamWs.js +43 -12
  85. package/lib/src/app/ws/logcatWs.js +48 -14
  86. package/lib/src/app/ws/nodeSocketRelay.js +167 -0
  87. package/lib/src/app/ws/upgradeRouter.js +215 -0
  88. package/lib/src/dashboard/event-manager.js +7 -6
  89. package/lib/src/data-service/device-service.js +152 -49
  90. package/lib/src/data-service/device-store.js +92 -10
  91. package/lib/src/data-service/deviceClaims.js +116 -0
  92. package/lib/src/data-service/deviceFieldOwners.js +32 -10
  93. package/lib/src/data-service/prisma-store.js +102 -31
  94. package/lib/src/device-managers/AndroidDeviceManager.js +40 -42
  95. package/lib/src/device-managers/HealthMonitorService.js +17 -2
  96. package/lib/src/device-managers/IOSDeviceManager.js +5 -1
  97. package/lib/src/device-managers/NodeDevices.js +7 -2
  98. package/lib/src/device-managers/android/AndroidH264StreamService.js +13 -5
  99. package/lib/src/device-managers/android/AndroidStreamService.js +9 -6
  100. package/lib/src/device-managers/android/previewHold.js +2 -2
  101. package/lib/src/device-managers/ios/IOSDiscoveryService.js +19 -8
  102. package/lib/src/device-managers/ios/IOSStreamService.js +162 -40
  103. package/lib/src/device-managers/localDeviceHosts.js +86 -0
  104. package/lib/src/device-managers/ownDeviceRow.js +38 -0
  105. package/lib/src/device-utils.js +78 -24
  106. package/lib/src/gateway/createHandoff.js +73 -0
  107. package/lib/src/gateway/defaultGateway.js +80 -0
  108. package/lib/src/gateway/forwardToNode.js +147 -0
  109. package/lib/src/gateway/hubSessionToken.js +356 -0
  110. package/lib/src/gateway/internalCall.js +90 -0
  111. package/lib/src/gateway/nodeSessionStatus.js +140 -0
  112. package/lib/src/gateway/nodeWebDriverUrl.js +139 -0
  113. package/lib/src/gateway/sessionCreate.js +136 -0
  114. package/lib/src/gateway/sessionGateway.js +201 -0
  115. package/lib/src/gateway/sessionLocator.js +100 -0
  116. package/lib/src/generated/client/edge.js +7 -4
  117. package/lib/src/generated/client/index-browser.js +4 -1
  118. package/lib/src/generated/client/index.d.ts +112 -1
  119. package/lib/src/generated/client/index.js +7 -4
  120. package/lib/src/generated/client/package.json +1 -1
  121. package/lib/src/generated/client/schema.prisma +9 -0
  122. package/lib/src/generated/client/wasm.js +4 -1
  123. package/lib/src/helpers/index.js +5 -1
  124. package/lib/src/logger.js +5 -0
  125. package/lib/src/middleware/authMiddleware.js +80 -0
  126. package/lib/src/middleware/commandAuth.js +31 -17
  127. package/lib/src/middleware/csrfMiddleware.js +3 -2
  128. package/lib/src/middleware/deviceAccessGuard.js +4 -1
  129. package/lib/src/middleware/sessionListingFilter.js +153 -0
  130. package/lib/src/middleware/sessionUpgradeGuard.js +203 -0
  131. package/lib/src/plugin.js +27 -1
  132. package/lib/src/prisma.js +2 -1
  133. package/lib/src/services/DeviceReconciler.js +5 -2
  134. package/lib/src/services/OrphanSweeper.js +12 -19
  135. package/lib/src/services/PortAllocator.js +75 -16
  136. package/lib/src/services/ServerManager.js +63 -30
  137. package/lib/src/services/SessionLifecycleService.js +335 -76
  138. package/lib/src/services/ShutdownCoordinator.js +7 -1
  139. package/lib/src/services/SocketServer.js +11 -2
  140. package/lib/src/services/device-access/LiveSessionOwners.js +53 -0
  141. package/lib/src/services/device-access/SessionOwnerResolver.js +74 -0
  142. package/lib/src/services/device-access/ticketActorAccess.js +3 -1
  143. package/lib/src/services/lease/LeaseOrphanSweeper.js +34 -6
  144. package/lib/src/services/lease/LeaseService.js +19 -5
  145. package/lib/src/services/session/nodeCreateCaps.js +55 -0
  146. package/lib/src/services/session/sessionCredentials.js +7 -59
  147. package/lib/src/sessions/CloudSession.js +12 -0
  148. package/lib/src/sessions/LocalSession.js +52 -26
  149. package/lib/src/sessions/RemoteSession.js +116 -9
  150. package/lib/src/sessions/SessionManager.js +49 -6
  151. package/lib/src/sessions/appiumUmbrella.js +32 -0
  152. package/lib/test/helpers/appium-umbrella.js +84 -0
  153. package/lib/test/helpers/fake-device-table.js +97 -0
  154. package/lib/test/helpers/loki-stores.js +41 -0
  155. package/lib/test/helpers/loopbackRequest.js +77 -0
  156. package/lib/test/helpers/own-node-id.js +29 -0
  157. package/lib/test/helpers/scratch-database.js +100 -0
  158. package/lib/test/helpers/scratch-port-leases.js +119 -0
  159. package/lib/test/helpers/test-container.js +35 -27
  160. package/lib/test/integration/androidDevices.spec.js +5 -4
  161. package/lib/test/integration/ios/01iOSSimulator.spec.js +6 -5
  162. package/lib/test/integration/ios/02iOSDevices.spec.js +3 -2
  163. package/lib/test/integration/prisma-device-store-add-devices.spec.js +14 -4
  164. package/lib/test/setup/scratch-default-database.js +32 -0
  165. package/lib/test/unit/AndroidDeviceManager.spec.js +56 -1
  166. package/lib/test/unit/DeviceModel.spec.js +9 -9
  167. package/lib/test/unit/HealingCascade.test.js +5 -1
  168. package/lib/test/unit/OrphanSweeper.test.js +17 -13
  169. package/lib/test/unit/SessionHeartbeatWrite.test.js +6 -7
  170. package/lib/test/unit/StreamTicketService.spec.js +4 -1
  171. package/lib/test/unit/TokenEndpoint.spec.js +17 -3
  172. package/lib/test/unit/aggregate-hotspots-session-scope.spec.js +5 -5
  173. package/lib/test/unit/android-h264-service.spec.js +24 -0
  174. package/lib/test/unit/android-stream-stall-eof.spec.js +10 -0
  175. package/lib/test/unit/apps-team-visibility.spec.js +16 -16
  176. package/lib/test/unit/auth-me-auth-disabled.test.js +7 -4
  177. package/lib/test/unit/authMiddleware.appTicket.spec.js +5 -5
  178. package/lib/test/unit/authMiddleware.bearer.spec.js +4 -1
  179. package/lib/test/unit/authMiddleware.mcpAudience.spec.js +4 -1
  180. package/lib/test/unit/authMiddleware.streamTicket.spec.js +19 -7
  181. package/lib/test/unit/authMiddleware.test.js +3 -0
  182. package/lib/test/unit/bug-report/route.spec.js +9 -9
  183. package/lib/test/unit/cliargs-admin-only.spec.js +3 -3
  184. package/lib/test/unit/clipboard-route.spec.js +22 -8
  185. package/lib/test/unit/command-auth-appium-server.spec.js +187 -32
  186. package/lib/test/unit/command-auth.spec.js +31 -31
  187. package/lib/test/unit/control-device-lookup.spec.js +9 -9
  188. package/lib/test/unit/control-forward-decision.spec.js +115 -0
  189. package/lib/test/unit/control-lookup-failure.spec.js +3 -3
  190. package/lib/test/unit/create-error-message.spec.js +43 -0
  191. package/lib/test/unit/create-handoff.spec.js +86 -0
  192. package/lib/test/unit/dashboard-events-team-scope.spec.js +6 -3
  193. package/lib/test/unit/device-access-guard.spec.js +66 -28
  194. package/lib/test/unit/device-service.spec.js +4 -0
  195. package/lib/test/unit/device-store-clear-at-boot.spec.js +48 -0
  196. package/lib/test/unit/device-sync-lost-update.spec.js +17 -89
  197. package/lib/test/unit/device-team-guard.spec.js +20 -20
  198. package/lib/test/unit/device-utils.spec.js +8 -0
  199. package/lib/test/unit/extract-team-cap.spec.js +65 -0
  200. package/lib/test/unit/grid-admin-only.spec.js +3 -3
  201. package/lib/test/unit/healing-tier-gate.spec.js +5 -1
  202. package/lib/test/unit/health-monitor-own-phones.spec.js +102 -0
  203. package/lib/test/unit/health-monitor-stream-lookup.spec.js +11 -1
  204. package/lib/test/unit/helpers.spec.js +27 -0
  205. package/lib/test/unit/hub-boot-sweep-recovery.spec.js +192 -0
  206. package/lib/test/unit/hub-create-once.spec.js +190 -0
  207. package/lib/test/unit/hub-create-session-umbrella.spec.js +160 -0
  208. package/lib/test/unit/hub-gateway-create-appium-server.spec.js +591 -0
  209. package/lib/test/unit/hub-node-control-forward.spec.js +608 -0
  210. package/lib/test/unit/hub-node-gateway-appium-server.spec.js +594 -0
  211. package/lib/test/unit/hub-node-race.spec.js +426 -0
  212. package/lib/test/unit/hub-node-same-host.spec.js +356 -0
  213. package/lib/test/unit/hub-register-removal.spec.js +165 -0
  214. package/lib/test/unit/hub-remote-session-heartbeat.spec.js +277 -0
  215. package/lib/test/unit/hub-routed-session-recovery.spec.js +151 -0
  216. package/lib/test/unit/hub-session-token.spec.js +265 -0
  217. package/lib/test/unit/insert-before-routes.spec.js +5 -5
  218. package/lib/test/unit/install-repository-app-team.spec.js +6 -2
  219. package/lib/test/unit/interceptor/MitmProxyHost.spec.js +23 -10
  220. package/lib/test/unit/internal-call.spec.js +181 -0
  221. package/lib/test/unit/ios-discovery-same-host.spec.js +193 -0
  222. package/lib/test/unit/ios-stream-appium-tunnel.spec.js +317 -0
  223. package/lib/test/unit/ios-stream-port-leases.spec.js +299 -0
  224. package/lib/test/unit/ios-wda-status-identity.spec.js +84 -0
  225. package/lib/test/unit/is-xenon-running.spec.js +69 -0
  226. package/lib/test/unit/lease/LeaseOrphanSweeper.spec.js +2 -2
  227. package/lib/test/unit/lease/LeaseService.spec.js +28 -1
  228. package/lib/test/unit/lease/lease-reap-held-phone.spec.js +154 -0
  229. package/lib/test/unit/lease/lease-sweeper-expiry.spec.js +107 -0
  230. package/lib/test/unit/lease/lease-team-visibility.spec.js +2 -2
  231. package/lib/test/unit/lease/lease-token-log-filter.spec.js +242 -64
  232. package/lib/test/unit/lease/lease-token-oracle.spec.js +20 -7
  233. package/lib/test/unit/lease/session-lease-proof.spec.js +8 -3
  234. package/lib/test/unit/logcat-ws.spec.js +12 -1
  235. package/lib/test/unit/loopback-request.spec.js +81 -0
  236. package/lib/test/unit/mark-node-busy-loki.spec.js +53 -0
  237. package/lib/test/unit/node-create-caps.spec.js +54 -0
  238. package/lib/test/unit/node-gateway-create-appium-server.spec.js +354 -0
  239. package/lib/test/unit/node-hub-session-owner.spec.js +223 -0
  240. package/lib/test/unit/node-phone-control.spec.js +131 -0
  241. package/lib/test/unit/node-socket-relay.spec.js +357 -0
  242. package/lib/test/unit/omni-vision.spec.js +7 -3
  243. package/lib/test/unit/plugin.spec.js +45 -4
  244. package/lib/test/unit/port-allocator-os-probe.spec.js +151 -0
  245. package/lib/test/unit/profile-router.test.js +11 -11
  246. package/lib/test/unit/queue-requester.spec.js +5 -0
  247. package/lib/test/unit/queue-team-scope-routes.spec.js +17 -16
  248. package/lib/test/unit/queue-visibility.spec.js +1 -1
  249. package/lib/test/unit/recording-downloads-visibility.spec.js +2 -2
  250. package/lib/test/unit/recording-instrumentation.spec.js +5 -0
  251. package/lib/test/unit/recording-source-ended.spec.js +5 -0
  252. package/lib/test/unit/recording-store.spec.js +9 -3
  253. package/lib/test/unit/recordings-library-routes.spec.js +51 -51
  254. package/lib/test/unit/recordings-write-visibility.spec.js +2 -2
  255. package/lib/test/unit/remote-session-create.spec.js +130 -0
  256. package/lib/test/unit/reservation-team-visibility.spec.js +5 -5
  257. package/lib/test/unit/reset-link.test.js +14 -14
  258. package/lib/test/unit/session-app-resolution.spec.js +14 -10
  259. package/lib/test/unit/session-assets.spec.js +9 -9
  260. package/lib/test/unit/session-attribution-wiring.spec.js +29 -2
  261. package/lib/test/unit/session-create-layer.spec.js +255 -0
  262. package/lib/test/unit/session-credential-strip.spec.js +25 -9
  263. package/lib/test/unit/session-credentials.spec.js +0 -47
  264. package/lib/test/unit/session-listing-auth.spec.js +345 -0
  265. package/lib/test/unit/session-locator.spec.js +250 -0
  266. package/lib/test/unit/session-node-calls.spec.js +174 -0
  267. package/lib/test/unit/session-owner-resolver.spec.js +107 -0
  268. package/lib/test/unit/session-recovery-routing.spec.js +118 -0
  269. package/lib/test/unit/session-upgrade-guard.spec.js +571 -0
  270. package/lib/test/unit/shutdown-drain-remote.spec.js +58 -0
  271. package/lib/test/unit/socketServer.bearer.spec.js +3 -1
  272. package/lib/test/unit/stream-leave-route.spec.js +19 -7
  273. package/lib/test/unit/stream-own-device-row.spec.js +164 -0
  274. package/lib/test/unit/stream-stop-ownership.spec.js +17 -5
  275. package/lib/test/unit/stream-stop-recording.spec.js +17 -5
  276. package/lib/test/unit/stream-ticket-identity.spec.js +26 -6
  277. package/lib/test/unit/stream-watchdog-timers.spec.js +46 -0
  278. package/lib/test/unit/upgrade-router.spec.js +446 -0
  279. package/lib/test/unit/users-router.test.js +11 -8
  280. package/lib/test/unit/verify-credential.spec.js +4 -1
  281. package/lib/test/unit/webdriver-info-route.spec.js +64 -0
  282. package/lib/test/unit/ws-upgrade-routing-appium-server.spec.js +500 -0
  283. package/lib/tsconfig.tsbuildinfo +1 -1
  284. package/package.json +3 -4
  285. package/prisma/migrations/20260929120000_device_claims/migration.sql +8 -0
  286. package/prisma/schema.prisma +9 -0
  287. package/lib/public/assets/BugReportButton-DKYsOdGV.js +0 -10
  288. package/lib/public/assets/device-explorer-DV8rWRxL.css +0 -1
  289. package/lib/src/proxy/wd-command-proxy.js +0 -221
@@ -1 +1 @@
1
- {"root":["../src/InternalHttpClient.ts","../src/PluginContext.ts","../src/XenonCapabilityManager.ts","../src/chromeUtils.ts","../src/config.ts","../src/device-utils.ts","../src/index.ts","../src/logger.ts","../src/plugin.ts","../src/prisma.ts","../src/app/index.ts","../src/app/insertBeforeRoutes.ts","../src/app/registerCommandAuth.ts","../src/app/swagger-docs.ts","../src/app/swagger.ts","../src/app/routers/androidH264Config.ts","../src/app/routers/apikeys.ts","../src/app/routers/apps.ts","../src/app/routers/audit.ts","../src/app/routers/auth.ts","../src/app/routers/bug-report.ts","../src/app/routers/build-export.ts","../src/app/routers/capabilities.ts","../src/app/routers/config.ts","../src/app/routers/control.ts","../src/app/routers/dashboard.ts","../src/app/routers/grid.ts","../src/app/routers/interceptor.ts","../src/app/routers/iosStreamPort.ts","../src/app/routers/ports.ts","../src/app/routers/processes.ts","../src/app/routers/profile.ts","../src/app/routers/profileIdentity.ts","../src/app/routers/projects.ts","../src/app/routers/recordingRequests.ts","../src/app/routers/recordings.ts","../src/app/routers/reservation.ts","../src/app/routers/sdk-leases.ts","../src/app/routers/sdk-version.ts","../src/app/routers/streamLeave.ts","../src/app/routers/streamStartConflict.ts","../src/app/routers/streamType.ts","../src/app/routers/teams.ts","../src/app/routers/users.ts","../src/app/routers/webhook.ts","../src/app/ws/h264StreamWs.ts","../src/app/ws/logcatWs.ts","../src/commands/handle.ts","../src/commands/index.ts","../src/dashboard/asset-manager.ts","../src/dashboard/commands.ts","../src/dashboard/event-manager.ts","../src/dashboard/services/app-service.ts","../src/dashboard/services/failure-analysis-service.ts","../src/dashboard/services/session-service.ts","../src/data-service/CircuitBreaker.ts","../src/data-service/config-service.ts","../src/data-service/db.ts","../src/data-service/device-service.ts","../src/data-service/device-store.interface.ts","../src/data-service/device-store.ts","../src/data-service/deviceColumns.ts","../src/data-service/deviceFieldOwners.ts","../src/data-service/pending-sessions-service.ts","../src/data-service/pluginArgs.ts","../src/data-service/prisma-service.ts","../src/data-service/prisma-store.ts","../src/data-service/queue-service.ts","../src/data-service/web-config-service.ts","../src/device-managers/AndroidDeviceManager.ts","../src/device-managers/ChromeDriverManager.ts","../src/device-managers/HealthMonitorService.ts","../src/device-managers/IOSDeviceManager.ts","../src/device-managers/NodeDevices.ts","../src/device-managers/clipboardErrors.ts","../src/device-managers/deviceIdentity.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/android/AndroidH264StreamService.ts","../src/device-managers/android/AndroidStreamService.ts","../src/device-managers/android/DeviceLockManager.ts","../src/device-managers/android/H264Multiplexer.ts","../src/device-managers/android/LogcatMultiplexer.ts","../src/device-managers/android/LogcatStreamService.ts","../src/device-managers/android/ScrcpyServerSession.ts","../src/device-managers/android/androidIdentity.ts","../src/device-managers/android/androidStreamReuse.ts","../src/device-managers/android/clipboardBroadcast.ts","../src/device-managers/android/displayState.ts","../src/device-managers/android/h264NalParser.ts","../src/device-managers/android/previewHold.ts","../src/device-managers/android/scrcpyVersion.ts","../src/device-managers/cloud/CapabilityManager.ts","../src/device-managers/cloud/Devices.ts","../src/device-managers/ios/IOSDiscoveryService.ts","../src/device-managers/ios/IOSLogStreamService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/WDAClient.ts","../src/device-managers/ios/appleIdentity.ts","../src/device-managers/ios/iosAppIds.ts","../src/device-managers/ios/iosBattery.ts","../src/device-managers/ios/iosStreamDiagnostics.ts","../src/device-managers/ios/tunnelProcess.ts","../src/enums/Capabilities.ts","../src/enums/Cloud.ts","../src/enums/Platform.ts","../src/enums/SessionType.ts","../src/enums/SocketEvents.ts","../src/generated/client/default.d.ts","../src/generated/client/default.js","../src/generated/client/edge.d.ts","../src/generated/client/edge.js","../src/generated/client/index-browser.js","../src/generated/client/index.d.ts","../src/generated/client/index.js","../src/generated/client/wasm.d.ts","../src/generated/client/wasm.js","../src/generated/client/runtime/edge-esm.js","../src/generated/client/runtime/edge.js","../src/generated/client/runtime/index-browser.d.ts","../src/generated/client/runtime/index-browser.js","../src/generated/client/runtime/library.d.ts","../src/generated/client/runtime/library.js","../src/generated/client/runtime/react-native.js","../src/generated/client/runtime/wasm.js","../src/helpers/UniversalMjpegProxy.ts","../src/helpers/ffmpegPath.ts","../src/helpers/index.ts","../src/helpers/networkAddresses.ts","../src/helpers/singleFlight.ts","../src/interceptors/CommandInterceptor.ts","../src/interfaces/ICloudManager.ts","../src/interfaces/IDevice.ts","../src/interfaces/IDeviceFilterOptions.ts","../src/interfaces/IDeviceManager.ts","../src/interfaces/IOptions.ts","../src/interfaces/IPluginArgs.ts","../src/interfaces/ISessionCapability.ts","../src/logging/sessionContext.ts","../src/middleware/authMiddleware.ts","../src/middleware/commandAuth.ts","../src/middleware/commandCaller.ts","../src/middleware/controlDevice.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/deviceAccessGuard.ts","../src/middleware/deviceTeamGuard.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/middleware/verifyCredential.ts","../src/profiling/AndroidAppProfiler.ts","../src/proxy/wd-command-proxy.ts","../src/scripts/generate-database-migration.ts","../src/scripts/goIosVersion.ts","../src/scripts/initialize-database.ts","../src/scripts/install-go-ios.ts","../src/scripts/prepare-prisma.ts","../src/scripts/run-migrations.ts","../src/services/AICommandService.ts","../src/services/AIService.ts","../src/services/ApiKeyService.ts","../src/services/CircuitBreaker.ts","../src/services/CleanupService.ts","../src/services/DeviceReconciler.ts","../src/services/DisplayStateService.ts","../src/services/EmailService.ts","../src/services/EventBus.ts","../src/services/EventLogService.ts","../src/services/InspectorService.ts","../src/services/InterceptorService.ts","../src/services/MetricsService.ts","../src/services/NetworkConditioningService.ts","../src/services/NotificationService.ts","../src/services/OrphanSweeper.ts","../src/services/PasswordResetService.ts","../src/services/PortAllocator.ts","../src/services/ProcessMetricsService.ts","../src/services/ProcessRegistry.ts","../src/services/RequestLogService.ts","../src/services/ResourceIsolationService.ts","../src/services/SecurityService.ts","../src/services/SelectorStateService.ts","../src/services/SelectorVerificationJob.ts","../src/services/ServerManager.ts","../src/services/SessionHeartbeatService.ts","../src/services/SessionLifecycleService.ts","../src/services/ShutdownCoordinator.ts","../src/services/SocketClient.ts","../src/services/SocketServer.ts","../src/services/TeamService.ts","../src/services/TracingService.ts","../src/services/UserService.ts","../src/services/UserSessionService.ts","../src/services/VideoPipelineService.ts","../src/services/fillMissingScreenSize.ts","../src/services/passwordResetLink.ts","../src/services/passwordResetMode.ts","../src/services/sessionTokenGate.ts","../src/services/artifacts/ArtifactStore.ts","../src/services/autowait/AutowaitService.ts","../src/services/autowait/waitFor.ts","../src/services/bug-report/BugReportService.ts","../src/services/bug-report/archive.ts","../src/services/bug-report/har-collector.ts","../src/services/bug-report/manifest.ts","../src/services/bug-report/readme.ts","../src/services/bug-report/types.ts","../src/services/bug-report/video-slice.ts","../src/services/bug-report/window.ts","../src/services/device-access/DeviceTeamResolver.ts","../src/services/device-access/SessionOwnerResolver.ts","../src/services/device-access/actor.ts","../src/services/device-access/appVisibility.ts","../src/services/device-access/callerTeamIds.ts","../src/services/device-access/deviceAccessPolicy.ts","../src/services/device-access/deviceVisibility.ts","../src/services/device-access/leaseOverride.ts","../src/services/device-access/queueVisibility.ts","../src/services/device-access/sessionVisibility.ts","../src/services/device-access/ticketActorAccess.ts","../src/services/healing/FuzzyXmlHealingProvider.ts","../src/services/healing/HealEtalonService.ts","../src/services/healing/HealedLocatorGenerator.ts","../src/services/healing/HealingMetrics.ts","../src/services/healing/HealingOrchestrator.ts","../src/services/healing/LlmHealingProvider.ts","../src/services/healing/OcrHealingProvider.ts","../src/services/healing/ResilioTreeHealingProvider.ts","../src/services/healing/VisualAiHealingProvider.ts","../src/services/healing/types.ts","../src/services/identity/bootstrap.ts","../src/services/identity/sessionCleanupCron.ts","../src/services/identity/userAuthorization.ts","../src/services/inspector/verifyLocator.ts","../src/services/interceptor/AndroidProxyAdapter.ts","../src/services/interceptor/CertManager.ts","../src/services/interceptor/HarBuilder.ts","../src/services/interceptor/HostFilter.ts","../src/services/interceptor/MitmProxyHost.ts","../src/services/interceptor/MockEngine.ts","../src/services/interceptor/RequestBuffer.ts","../src/services/interceptor/SessionArchive.ts","../src/services/interceptor/types.ts","../src/services/lease/LeaseOrphanSweeper.ts","../src/services/lease/LeaseService.ts","../src/services/lease/buildCapabilityBag.ts","../src/services/lease/leaseSessionCaps.ts","../src/services/lease/leaseToken.ts","../src/services/logcat/PackageResolver.ts","../src/services/logcat/logSource.ts","../src/services/logcat/logcatParse.ts","../src/services/logcat/ostraceParse.ts","../src/services/omni-vision/OmniVisionService.ts","../src/services/omni-vision/VisionAssertionService.ts","../src/services/ports/PortAllocatorClient.ts","../src/services/ports/PortAllocatorService.ts","../src/services/recording/RecordingOrchestrator.ts","../src/services/recording/activeRecordings.ts","../src/services/recording/annotation-render.ts","../src/services/recording/annotationImage.ts","../src/services/recording/busy-precheck.ts","../src/services/recording/concurrency-gate.ts","../src/services/recording/ensureMjpegForRecording.ts","../src/services/recording/manualLock.ts","../src/services/recording/probeDuration.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/recording/recordingCleanup.ts","../src/services/recording/recordingFiles.ts","../src/services/recording/recordingSummary.ts","../src/services/recording/recordingTiming.ts","../src/services/session/appCapability.ts","../src/services/session/sessionCredentials.ts","../src/services/session/sessionIdentity.ts","../src/services/session/xenonOptions.ts","../src/services/telemetry/attributes.ts","../src/services/token/AppDownloadTicketService.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/services/token/mcpScopes.ts","../src/services/token/singleUseLedger.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/types/CLIArgs.ts","../src/types/CloudArgs.ts","../src/types/CloudSchema.ts","../src/types/DeviceType.ts","../src/types/DeviceUpdate.ts","../src/types/IOSDevice.ts","../src/types/Platform.ts","../src/types/SessionStatus.ts","../src/types/express.d.ts","../src/types/healing.d.ts","../src/types/identity.ts","../src/validators/CapabilityValidator.ts","../test/e2e/e2ehelper.ts","../test/e2e/plugin-harness.ts","../test/e2e/plugin.spec.ts","../test/e2e/startup-verification.spec.ts","../test/e2e/telemetry_verification.spec.ts","../test/e2e/video-recording-test.spec.js","../test/e2e/android/conf.spec.js","../test/e2e/android/conf2.spec.js","../test/e2e/android/conf3.spec.js","../test/e2e/hubnode/forward-request.spec.ts","../test/e2e/hubnode/hubnode.spec.ts","../test/e2e/ios/conf1.spec.js","../test/e2e/ios/conf2.spec.js","../test/helpers/artifact-store.ts","../test/helpers/container-registration.ts","../test/helpers/loopbackServer.ts","../test/helpers/seedUser.ts","../test/helpers/test-container.ts","../test/integration/androidDevices.spec.ts","../test/integration/audit-ingest.spec.ts","../test/integration/auth-flow.spec.ts","../test/integration/auth-rate-limit.spec.ts","../test/integration/bug-report-route.spec.ts","../test/integration/cliArgs.js","../test/integration/cross-workflow.spec.ts","../test/integration/forgot-password-rate-limit.spec.ts","../test/integration/forgot-password.spec.ts","../test/integration/healing-events-sessionfilter.spec.ts","../test/integration/legacy-deprecation-headers.spec.ts","../test/integration/migration.spec.ts","../test/integration/node-pair-auth-rest.spec.ts","../test/integration/ports-router.spec.ts","../test/integration/prisma-device-store-add-devices.spec.ts","../test/integration/prisma-device-store-team-filter.spec.ts","../test/integration/profile-tokens.spec.ts","../test/integration/recordings-router.spec.ts","../test/integration/reset-revokes-sessions.spec.ts","../test/integration/role-matrix.spec.ts","../test/integration/sdk-leases-router.spec.ts","../test/integration/sdk-version.spec.ts","../test/integration/selector-health-endpoint.spec.ts","../test/integration/selector-state-flow.spec.ts","../test/integration/team-membership-migration.spec.ts","../test/integration/team-visibility-apps.spec.ts","../test/integration/team-visibility-control.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-leases.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/team-visibility-sessions.spec.ts","../test/integration/users-flow.spec.ts","../test/integration/users-lockout.spec.ts","../test/integration/ios/01iOSSimulator.spec.ts","../test/integration/ios/02iOSDevices.spec.ts","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/AppDownloadTicketService.spec.ts","../test/unit/ArtifactStore.spec.ts","../test/unit/AutowaitService.spec.ts","../test/unit/CapabilitiesRouter.spec.ts","../test/unit/ChromeDriverManager.spec.js","../test/unit/CleanupService.spec.ts","../test/unit/CommandInterceptor.autowait.spec.ts","../test/unit/DeviceModel.spec.ts","../test/unit/EmailService.test.ts","../test/unit/EventLogService.spec.ts","../test/unit/FuzzyXmlHealingProvider.test.ts","../test/unit/GetAdbOriginal.js","../test/unit/HealingCascade.test.ts","../test/unit/IOSDeviceManager.spec.js","../test/unit/JwtKeyService.spec.ts","../test/unit/McpScopes.spec.ts","../test/unit/OrphanSweeper.test.ts","../test/unit/PasswordResetService.test.ts","../test/unit/PortAllocator.test.ts","../test/unit/ProcessRegistry.test.ts","../test/unit/ProjectsRouter.spec.ts","../test/unit/RemoteIOs.spec.js","../test/unit/ResilioTreeHealingProvider.test.ts","../test/unit/SessionHeartbeatWrite.test.ts","../test/unit/SessionLifecycleCaps.spec.ts","../test/unit/SessionTokenGate.spec.ts","../test/unit/StreamTicketService.spec.ts","../test/unit/TeamService.test.ts","../test/unit/TokenEndpoint.spec.ts","../test/unit/UserService.test.ts","../test/unit/UserSessionService.test.ts","../test/unit/XenonCapabilityManager.spec.ts","../test/unit/active-recordings.spec.ts","../test/unit/aggregate-hotspots-session-scope.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/android-clipboard.spec.ts","../test/unit/android-h264-config.spec.ts","../test/unit/android-h264-service.spec.ts","../test/unit/android-identity.spec.ts","../test/unit/android-preview-hold.spec.ts","../test/unit/android-stream-adb-path.spec.ts","../test/unit/android-stream-encoder.spec.ts","../test/unit/android-stream-fast-start.spec.ts","../test/unit/android-stream-release.spec.ts","../test/unit/android-stream-reuse-service.spec.ts","../test/unit/android-stream-reuse.spec.ts","../test/unit/android-stream-stall-eof.spec.ts","../test/unit/annotation-image.spec.ts","../test/unit/annotation-render.spec.ts","../test/unit/apple-identity.spec.ts","../test/unit/apps-download.spec.ts","../test/unit/apps-team-visibility.spec.ts","../test/unit/auth-disabled-resolution.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.appTicket.spec.ts","../test/unit/authMiddleware.bearer.spec.ts","../test/unit/authMiddleware.mcpAudience.spec.ts","../test/unit/authMiddleware.streamTicket.spec.ts","../test/unit/authMiddleware.test.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/cliargs-admin-only.spec.ts","../test/unit/clipboard-route.spec.ts","../test/unit/command-auth-appium-server.spec.ts","../test/unit/command-auth.spec.ts","../test/unit/command-caller.spec.ts","../test/unit/commands.spec.js","../test/unit/composite-geometry.spec.ts","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/container-registration.spec.ts","../test/unit/control-device-lookup.spec.ts","../test/unit/control-lookup-failure.spec.ts","../test/unit/dashboard-events-team-scope.spec.ts","../test/unit/device-access-guard.spec.ts","../test/unit/device-access-policy.spec.ts","../test/unit/device-columns.spec.ts","../test/unit/device-service.spec.ts","../test/unit/device-sync-lost-update.spec.ts","../test/unit/device-team-guard.spec.ts","../test/unit/device-team-resolver.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/display-state.spec.ts","../test/unit/enrich-devices-team-names.test.ts","../test/unit/event-manager-regression-hook.spec.ts","../test/unit/extract-access-key-token-pair.test.ts","../test/unit/ffmpeg-path.spec.ts","../test/unit/fill-missing-screen-size.spec.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/go-ios-version.spec.ts","../test/unit/grid-admin-only.spec.ts","../test/unit/h264-multiplexer.spec.ts","../test/unit/h264-nal-parser.spec.ts","../test/unit/h264-ws-frame.spec.ts","../test/unit/healing-instrumentation.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/healing-tier-gate.spec.ts","../test/unit/health-monitor-stream-lookup.spec.ts","../test/unit/helpers.spec.ts","../test/unit/insert-before-routes.spec.ts","../test/unit/inspector-hierarchy.spec.ts","../test/unit/install-repository-app-team.spec.ts","../test/unit/ios-idle-hold.spec.ts","../test/unit/ios-stream-port.spec.ts","../test/unit/ios-tunnel-process.spec.ts","../test/unit/iosBattery.spec.ts","../test/unit/iosStreamDiagnostics.spec.ts","../test/unit/logcat-multiplexer.spec.ts","../test/unit/logcat-parse.spec.ts","../test/unit/logcat-stream-service.spec.ts","../test/unit/logcat-ws.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/manualLock.test.ts","../test/unit/mjpeg-proxy-cache.spec.ts","../test/unit/network-addresses.test.ts","../test/unit/normalize-eol.spec.js","../test/unit/omni-vision.spec.ts","../test/unit/ostrace-parse.spec.ts","../test/unit/package-resolver.spec.ts","../test/unit/passwordResetMode.test.ts","../test/unit/plugin.spec.ts","../test/unit/port-exhaustion.spec.ts","../test/unit/prisma.spec.ts","../test/unit/probe-duration.spec.ts","../test/unit/profile-router.test.ts","../test/unit/profileIdentity.spec.ts","../test/unit/proof-bundle.spec.ts","../test/unit/queue-requester.spec.ts","../test/unit/queue-team-scope-routes.spec.ts","../test/unit/queue-visibility.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-cleanup.spec.ts","../test/unit/recording-downloads-visibility.spec.ts","../test/unit/recording-files.spec.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-requests.spec.ts","../test/unit/recording-source-ended.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/recording-summary.spec.ts","../test/unit/recording-timing.spec.ts","../test/unit/recordings-library-routes.spec.ts","../test/unit/recordings-write-visibility.spec.ts","../test/unit/remux-to-standard-mp4.spec.ts","../test/unit/reservation-team-visibility.spec.ts","../test/unit/reset-link.test.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/schema-required-args.spec.ts","../test/unit/scrcpy-server-session.spec.ts","../test/unit/scrcpy-version.spec.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/session-app-resolution.spec.ts","../test/unit/session-assets.spec.ts","../test/unit/session-attribution-wiring.spec.ts","../test/unit/session-credential-strip.spec.ts","../test/unit/session-credentials.spec.ts","../test/unit/session-identity.spec.ts","../test/unit/session-owner-resolver.spec.ts","../test/unit/session-visibility.spec.ts","../test/unit/shutdown-sync-nets.spec.ts","../test/unit/single-flight.spec.ts","../test/unit/socket-team-scope.integration.spec.ts","../test/unit/socketServer.bearer.spec.ts","../test/unit/socketServer.scopedEmit.spec.ts","../test/unit/socketServer.sessionCookie.spec.ts","../test/unit/stored-session-capabilities.spec.ts","../test/unit/stream-leave-route.spec.ts","../test/unit/stream-leave.spec.ts","../test/unit/stream-start-conflict.spec.ts","../test/unit/stream-status-type.spec.ts","../test/unit/stream-stop-ownership.spec.ts","../test/unit/stream-stop-recording.spec.ts","../test/unit/stream-ticket-identity.spec.ts","../test/unit/sync-dir.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/verify-credential.spec.ts","../test/unit/verify-locator.spec.ts","../test/unit/video-pipeline-args.spec.ts","../test/unit/video-pipeline-exit.spec.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/wda-cap-injection.spec.ts","../test/unit/xenon-options.spec.ts","../test/unit/bug-report/archive.spec.ts","../test/unit/bug-report/har-collector.spec.ts","../test/unit/bug-report/manifest.spec.ts","../test/unit/bug-report/readme.spec.ts","../test/unit/bug-report/route.spec.ts","../test/unit/bug-report/service.spec.ts","../test/unit/bug-report/video-slice.spec.ts","../test/unit/bug-report/window.spec.ts","../test/unit/fixtures/device.config.js","../test/unit/fixtures/devices.js","../test/unit/interceptor/AndroidProxyAdapter.spec.ts","../test/unit/interceptor/CertManager.spec.ts","../test/unit/interceptor/HarBuilder.spec.ts","../test/unit/interceptor/HostFilter.spec.ts","../test/unit/interceptor/MitmProxyHost.spec.ts","../test/unit/interceptor/MockEngine.spec.ts","../test/unit/interceptor/RequestBuffer.spec.ts","../test/unit/interceptor/SessionArchive.spec.ts","../test/unit/lease/LeaseOrphanSweeper.spec.ts","../test/unit/lease/LeaseService.spec.ts","../test/unit/lease/allocate-lease-branch.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/lease-override.spec.ts","../test/unit/lease/lease-session-ownership.spec.ts","../test/unit/lease/lease-team-visibility.spec.ts","../test/unit/lease/lease-token-log-filter.spec.ts","../test/unit/lease/lease-token-oracle.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/lease/nodePairAuth.spec.ts","../test/unit/lease/session-lease-proof.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}
1
+ {"root":["../src/InternalHttpClient.ts","../src/PluginContext.ts","../src/XenonCapabilityManager.ts","../src/chromeUtils.ts","../src/config.ts","../src/device-utils.ts","../src/index.ts","../src/logger.ts","../src/plugin.ts","../src/prisma.ts","../src/app/appiumBasePath.ts","../src/app/index.ts","../src/app/insertBeforeRoutes.ts","../src/app/registerCommandAuth.ts","../src/app/swagger-docs.ts","../src/app/swagger.ts","../src/app/routers/androidH264Config.ts","../src/app/routers/apikeys.ts","../src/app/routers/apps.ts","../src/app/routers/audit.ts","../src/app/routers/auth.ts","../src/app/routers/bug-report.ts","../src/app/routers/build-export.ts","../src/app/routers/capabilities.ts","../src/app/routers/config.ts","../src/app/routers/control.ts","../src/app/routers/dashboard.ts","../src/app/routers/grid.ts","../src/app/routers/interceptor.ts","../src/app/routers/iosStreamPort.ts","../src/app/routers/nodePhoneControl.ts","../src/app/routers/ports.ts","../src/app/routers/processes.ts","../src/app/routers/profile.ts","../src/app/routers/profileIdentity.ts","../src/app/routers/projects.ts","../src/app/routers/recordingRequests.ts","../src/app/routers/recordings.ts","../src/app/routers/reservation.ts","../src/app/routers/sdk-leases.ts","../src/app/routers/sdk-version.ts","../src/app/routers/streamLeave.ts","../src/app/routers/streamStartConflict.ts","../src/app/routers/streamType.ts","../src/app/routers/teams.ts","../src/app/routers/users.ts","../src/app/routers/webhook.ts","../src/app/ws/h264StreamWs.ts","../src/app/ws/logcatWs.ts","../src/app/ws/nodeSocketRelay.ts","../src/app/ws/upgradeRouter.ts","../src/commands/handle.ts","../src/commands/index.ts","../src/dashboard/asset-manager.ts","../src/dashboard/commands.ts","../src/dashboard/event-manager.ts","../src/dashboard/services/app-service.ts","../src/dashboard/services/failure-analysis-service.ts","../src/dashboard/services/session-service.ts","../src/data-service/CircuitBreaker.ts","../src/data-service/config-service.ts","../src/data-service/db.ts","../src/data-service/device-service.ts","../src/data-service/device-store.interface.ts","../src/data-service/device-store.ts","../src/data-service/deviceClaims.ts","../src/data-service/deviceColumns.ts","../src/data-service/deviceFieldOwners.ts","../src/data-service/pending-sessions-service.ts","../src/data-service/pluginArgs.ts","../src/data-service/prisma-service.ts","../src/data-service/prisma-store.ts","../src/data-service/queue-service.ts","../src/data-service/web-config-service.ts","../src/device-managers/AndroidDeviceManager.ts","../src/device-managers/ChromeDriverManager.ts","../src/device-managers/HealthMonitorService.ts","../src/device-managers/IOSDeviceManager.ts","../src/device-managers/NodeDevices.ts","../src/device-managers/clipboardErrors.ts","../src/device-managers/deviceIdentity.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/localDeviceHosts.ts","../src/device-managers/ownDeviceRow.ts","../src/device-managers/android/AndroidH264StreamService.ts","../src/device-managers/android/AndroidStreamService.ts","../src/device-managers/android/DeviceLockManager.ts","../src/device-managers/android/H264Multiplexer.ts","../src/device-managers/android/LogcatMultiplexer.ts","../src/device-managers/android/LogcatStreamService.ts","../src/device-managers/android/ScrcpyServerSession.ts","../src/device-managers/android/androidIdentity.ts","../src/device-managers/android/androidStreamReuse.ts","../src/device-managers/android/clipboardBroadcast.ts","../src/device-managers/android/displayState.ts","../src/device-managers/android/h264NalParser.ts","../src/device-managers/android/previewHold.ts","../src/device-managers/android/scrcpyVersion.ts","../src/device-managers/cloud/CapabilityManager.ts","../src/device-managers/cloud/Devices.ts","../src/device-managers/ios/IOSDiscoveryService.ts","../src/device-managers/ios/IOSLogStreamService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/WDAClient.ts","../src/device-managers/ios/appleIdentity.ts","../src/device-managers/ios/iosAppIds.ts","../src/device-managers/ios/iosBattery.ts","../src/device-managers/ios/iosStreamDiagnostics.ts","../src/device-managers/ios/tunnelProcess.ts","../src/enums/Capabilities.ts","../src/enums/Cloud.ts","../src/enums/Platform.ts","../src/enums/SessionType.ts","../src/enums/SocketEvents.ts","../src/gateway/createHandoff.ts","../src/gateway/defaultGateway.ts","../src/gateway/forwardToNode.ts","../src/gateway/hubSessionToken.ts","../src/gateway/internalCall.ts","../src/gateway/nodeSessionStatus.ts","../src/gateway/nodeWebDriverUrl.ts","../src/gateway/sessionCreate.ts","../src/gateway/sessionGateway.ts","../src/gateway/sessionLocator.ts","../src/generated/client/default.d.ts","../src/generated/client/default.js","../src/generated/client/edge.d.ts","../src/generated/client/edge.js","../src/generated/client/index-browser.js","../src/generated/client/index.d.ts","../src/generated/client/index.js","../src/generated/client/wasm.d.ts","../src/generated/client/wasm.js","../src/generated/client/runtime/edge-esm.js","../src/generated/client/runtime/edge.js","../src/generated/client/runtime/index-browser.d.ts","../src/generated/client/runtime/index-browser.js","../src/generated/client/runtime/library.d.ts","../src/generated/client/runtime/library.js","../src/generated/client/runtime/react-native.js","../src/generated/client/runtime/wasm.js","../src/helpers/UniversalMjpegProxy.ts","../src/helpers/ffmpegPath.ts","../src/helpers/index.ts","../src/helpers/networkAddresses.ts","../src/helpers/singleFlight.ts","../src/interceptors/CommandInterceptor.ts","../src/interfaces/ICloudManager.ts","../src/interfaces/IDevice.ts","../src/interfaces/IDeviceFilterOptions.ts","../src/interfaces/IDeviceManager.ts","../src/interfaces/IOptions.ts","../src/interfaces/IPluginArgs.ts","../src/interfaces/ISessionCapability.ts","../src/logging/sessionContext.ts","../src/middleware/authMiddleware.ts","../src/middleware/commandAuth.ts","../src/middleware/commandCaller.ts","../src/middleware/controlDevice.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/deviceAccessGuard.ts","../src/middleware/deviceTeamGuard.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/middleware/sessionListingFilter.ts","../src/middleware/sessionUpgradeGuard.ts","../src/middleware/verifyCredential.ts","../src/profiling/AndroidAppProfiler.ts","../src/scripts/generate-database-migration.ts","../src/scripts/goIosVersion.ts","../src/scripts/initialize-database.ts","../src/scripts/install-go-ios.ts","../src/scripts/prepare-prisma.ts","../src/scripts/run-migrations.ts","../src/services/AICommandService.ts","../src/services/AIService.ts","../src/services/ApiKeyService.ts","../src/services/CircuitBreaker.ts","../src/services/CleanupService.ts","../src/services/DeviceReconciler.ts","../src/services/DisplayStateService.ts","../src/services/EmailService.ts","../src/services/EventBus.ts","../src/services/EventLogService.ts","../src/services/InspectorService.ts","../src/services/InterceptorService.ts","../src/services/MetricsService.ts","../src/services/NetworkConditioningService.ts","../src/services/NotificationService.ts","../src/services/OrphanSweeper.ts","../src/services/PasswordResetService.ts","../src/services/PortAllocator.ts","../src/services/ProcessMetricsService.ts","../src/services/ProcessRegistry.ts","../src/services/RequestLogService.ts","../src/services/ResourceIsolationService.ts","../src/services/SecurityService.ts","../src/services/SelectorStateService.ts","../src/services/SelectorVerificationJob.ts","../src/services/ServerManager.ts","../src/services/SessionHeartbeatService.ts","../src/services/SessionLifecycleService.ts","../src/services/ShutdownCoordinator.ts","../src/services/SocketClient.ts","../src/services/SocketServer.ts","../src/services/TeamService.ts","../src/services/TracingService.ts","../src/services/UserService.ts","../src/services/UserSessionService.ts","../src/services/VideoPipelineService.ts","../src/services/fillMissingScreenSize.ts","../src/services/passwordResetLink.ts","../src/services/passwordResetMode.ts","../src/services/sessionTokenGate.ts","../src/services/artifacts/ArtifactStore.ts","../src/services/autowait/AutowaitService.ts","../src/services/autowait/waitFor.ts","../src/services/bug-report/BugReportService.ts","../src/services/bug-report/archive.ts","../src/services/bug-report/har-collector.ts","../src/services/bug-report/manifest.ts","../src/services/bug-report/readme.ts","../src/services/bug-report/types.ts","../src/services/bug-report/video-slice.ts","../src/services/bug-report/window.ts","../src/services/device-access/DeviceTeamResolver.ts","../src/services/device-access/LiveSessionOwners.ts","../src/services/device-access/SessionOwnerResolver.ts","../src/services/device-access/actor.ts","../src/services/device-access/appVisibility.ts","../src/services/device-access/callerTeamIds.ts","../src/services/device-access/deviceAccessPolicy.ts","../src/services/device-access/deviceVisibility.ts","../src/services/device-access/leaseOverride.ts","../src/services/device-access/queueVisibility.ts","../src/services/device-access/sessionVisibility.ts","../src/services/device-access/ticketActorAccess.ts","../src/services/healing/FuzzyXmlHealingProvider.ts","../src/services/healing/HealEtalonService.ts","../src/services/healing/HealedLocatorGenerator.ts","../src/services/healing/HealingMetrics.ts","../src/services/healing/HealingOrchestrator.ts","../src/services/healing/LlmHealingProvider.ts","../src/services/healing/OcrHealingProvider.ts","../src/services/healing/ResilioTreeHealingProvider.ts","../src/services/healing/VisualAiHealingProvider.ts","../src/services/healing/types.ts","../src/services/identity/bootstrap.ts","../src/services/identity/sessionCleanupCron.ts","../src/services/identity/userAuthorization.ts","../src/services/inspector/verifyLocator.ts","../src/services/interceptor/AndroidProxyAdapter.ts","../src/services/interceptor/CertManager.ts","../src/services/interceptor/HarBuilder.ts","../src/services/interceptor/HostFilter.ts","../src/services/interceptor/MitmProxyHost.ts","../src/services/interceptor/MockEngine.ts","../src/services/interceptor/RequestBuffer.ts","../src/services/interceptor/SessionArchive.ts","../src/services/interceptor/types.ts","../src/services/lease/LeaseOrphanSweeper.ts","../src/services/lease/LeaseService.ts","../src/services/lease/buildCapabilityBag.ts","../src/services/lease/leaseSessionCaps.ts","../src/services/lease/leaseToken.ts","../src/services/logcat/PackageResolver.ts","../src/services/logcat/logSource.ts","../src/services/logcat/logcatParse.ts","../src/services/logcat/ostraceParse.ts","../src/services/omni-vision/OmniVisionService.ts","../src/services/omni-vision/VisionAssertionService.ts","../src/services/ports/PortAllocatorClient.ts","../src/services/ports/PortAllocatorService.ts","../src/services/recording/RecordingOrchestrator.ts","../src/services/recording/activeRecordings.ts","../src/services/recording/annotation-render.ts","../src/services/recording/annotationImage.ts","../src/services/recording/busy-precheck.ts","../src/services/recording/concurrency-gate.ts","../src/services/recording/ensureMjpegForRecording.ts","../src/services/recording/manualLock.ts","../src/services/recording/probeDuration.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/recording/recordingCleanup.ts","../src/services/recording/recordingFiles.ts","../src/services/recording/recordingSummary.ts","../src/services/recording/recordingTiming.ts","../src/services/session/appCapability.ts","../src/services/session/nodeCreateCaps.ts","../src/services/session/sessionCredentials.ts","../src/services/session/sessionIdentity.ts","../src/services/session/xenonOptions.ts","../src/services/telemetry/attributes.ts","../src/services/token/AppDownloadTicketService.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/services/token/mcpScopes.ts","../src/services/token/singleUseLedger.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/sessions/appiumUmbrella.ts","../src/types/CLIArgs.ts","../src/types/CloudArgs.ts","../src/types/CloudSchema.ts","../src/types/DeviceType.ts","../src/types/DeviceUpdate.ts","../src/types/IOSDevice.ts","../src/types/Platform.ts","../src/types/SessionStatus.ts","../src/types/express.d.ts","../src/types/healing.d.ts","../src/types/identity.ts","../src/validators/CapabilityValidator.ts","../test/e2e/e2ehelper.ts","../test/e2e/plugin-harness.ts","../test/e2e/plugin.spec.ts","../test/e2e/startup-verification.spec.ts","../test/e2e/telemetry_verification.spec.ts","../test/e2e/video-recording-test.spec.js","../test/e2e/android/conf.spec.js","../test/e2e/android/conf2.spec.js","../test/e2e/android/conf3.spec.js","../test/e2e/hubnode/forward-request.spec.ts","../test/e2e/hubnode/hubnode.spec.ts","../test/e2e/ios/conf1.spec.js","../test/e2e/ios/conf2.spec.js","../test/helpers/appium-umbrella.ts","../test/helpers/artifact-store.ts","../test/helpers/container-registration.ts","../test/helpers/fake-device-table.ts","../test/helpers/loki-stores.ts","../test/helpers/loopbackRequest.ts","../test/helpers/loopbackServer.ts","../test/helpers/own-node-id.ts","../test/helpers/scratch-database.ts","../test/helpers/scratch-port-leases.ts","../test/helpers/seedUser.ts","../test/helpers/test-container.ts","../test/integration/androidDevices.spec.ts","../test/integration/audit-ingest.spec.ts","../test/integration/auth-flow.spec.ts","../test/integration/auth-rate-limit.spec.ts","../test/integration/bug-report-route.spec.ts","../test/integration/cliArgs.js","../test/integration/cross-workflow.spec.ts","../test/integration/forgot-password-rate-limit.spec.ts","../test/integration/forgot-password.spec.ts","../test/integration/healing-events-sessionfilter.spec.ts","../test/integration/legacy-deprecation-headers.spec.ts","../test/integration/migration.spec.ts","../test/integration/node-pair-auth-rest.spec.ts","../test/integration/ports-router.spec.ts","../test/integration/prisma-device-store-add-devices.spec.ts","../test/integration/prisma-device-store-team-filter.spec.ts","../test/integration/profile-tokens.spec.ts","../test/integration/recordings-router.spec.ts","../test/integration/reset-revokes-sessions.spec.ts","../test/integration/role-matrix.spec.ts","../test/integration/sdk-leases-router.spec.ts","../test/integration/sdk-version.spec.ts","../test/integration/selector-health-endpoint.spec.ts","../test/integration/selector-state-flow.spec.ts","../test/integration/team-membership-migration.spec.ts","../test/integration/team-visibility-apps.spec.ts","../test/integration/team-visibility-control.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-leases.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/team-visibility-sessions.spec.ts","../test/integration/users-flow.spec.ts","../test/integration/users-lockout.spec.ts","../test/integration/ios/01iOSSimulator.spec.ts","../test/integration/ios/02iOSDevices.spec.ts","../test/setup/scratch-default-database.js","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/AppDownloadTicketService.spec.ts","../test/unit/ArtifactStore.spec.ts","../test/unit/AutowaitService.spec.ts","../test/unit/CapabilitiesRouter.spec.ts","../test/unit/ChromeDriverManager.spec.js","../test/unit/CleanupService.spec.ts","../test/unit/CommandInterceptor.autowait.spec.ts","../test/unit/DeviceModel.spec.ts","../test/unit/EmailService.test.ts","../test/unit/EventLogService.spec.ts","../test/unit/FuzzyXmlHealingProvider.test.ts","../test/unit/GetAdbOriginal.js","../test/unit/HealingCascade.test.ts","../test/unit/IOSDeviceManager.spec.js","../test/unit/JwtKeyService.spec.ts","../test/unit/McpScopes.spec.ts","../test/unit/OrphanSweeper.test.ts","../test/unit/PasswordResetService.test.ts","../test/unit/PortAllocator.test.ts","../test/unit/ProcessRegistry.test.ts","../test/unit/ProjectsRouter.spec.ts","../test/unit/RemoteIOs.spec.js","../test/unit/ResilioTreeHealingProvider.test.ts","../test/unit/SessionHeartbeatWrite.test.ts","../test/unit/SessionLifecycleCaps.spec.ts","../test/unit/SessionTokenGate.spec.ts","../test/unit/StreamTicketService.spec.ts","../test/unit/TeamService.test.ts","../test/unit/TokenEndpoint.spec.ts","../test/unit/UserService.test.ts","../test/unit/UserSessionService.test.ts","../test/unit/XenonCapabilityManager.spec.ts","../test/unit/active-recordings.spec.ts","../test/unit/aggregate-hotspots-session-scope.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/android-clipboard.spec.ts","../test/unit/android-h264-config.spec.ts","../test/unit/android-h264-service.spec.ts","../test/unit/android-identity.spec.ts","../test/unit/android-preview-hold.spec.ts","../test/unit/android-stream-adb-path.spec.ts","../test/unit/android-stream-encoder.spec.ts","../test/unit/android-stream-fast-start.spec.ts","../test/unit/android-stream-release.spec.ts","../test/unit/android-stream-reuse-service.spec.ts","../test/unit/android-stream-reuse.spec.ts","../test/unit/android-stream-stall-eof.spec.ts","../test/unit/annotation-image.spec.ts","../test/unit/annotation-render.spec.ts","../test/unit/apple-identity.spec.ts","../test/unit/apps-download.spec.ts","../test/unit/apps-team-visibility.spec.ts","../test/unit/auth-disabled-resolution.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.appTicket.spec.ts","../test/unit/authMiddleware.bearer.spec.ts","../test/unit/authMiddleware.mcpAudience.spec.ts","../test/unit/authMiddleware.streamTicket.spec.ts","../test/unit/authMiddleware.test.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/cliargs-admin-only.spec.ts","../test/unit/clipboard-route.spec.ts","../test/unit/command-auth-appium-server.spec.ts","../test/unit/command-auth.spec.ts","../test/unit/command-caller.spec.ts","../test/unit/commands.spec.js","../test/unit/composite-geometry.spec.ts","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/container-registration.spec.ts","../test/unit/control-device-lookup.spec.ts","../test/unit/control-forward-decision.spec.ts","../test/unit/control-lookup-failure.spec.ts","../test/unit/create-error-message.spec.ts","../test/unit/create-handoff.spec.ts","../test/unit/dashboard-events-team-scope.spec.ts","../test/unit/device-access-guard.spec.ts","../test/unit/device-access-policy.spec.ts","../test/unit/device-columns.spec.ts","../test/unit/device-service.spec.ts","../test/unit/device-store-clear-at-boot.spec.ts","../test/unit/device-sync-lost-update.spec.ts","../test/unit/device-team-guard.spec.ts","../test/unit/device-team-resolver.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/display-state.spec.ts","../test/unit/enrich-devices-team-names.test.ts","../test/unit/event-manager-regression-hook.spec.ts","../test/unit/extract-access-key-token-pair.test.ts","../test/unit/extract-team-cap.spec.ts","../test/unit/ffmpeg-path.spec.ts","../test/unit/fill-missing-screen-size.spec.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/go-ios-version.spec.ts","../test/unit/grid-admin-only.spec.ts","../test/unit/h264-multiplexer.spec.ts","../test/unit/h264-nal-parser.spec.ts","../test/unit/h264-ws-frame.spec.ts","../test/unit/healing-instrumentation.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/healing-tier-gate.spec.ts","../test/unit/health-monitor-own-phones.spec.ts","../test/unit/health-monitor-stream-lookup.spec.ts","../test/unit/helpers.spec.ts","../test/unit/hub-boot-sweep-recovery.spec.ts","../test/unit/hub-create-once.spec.ts","../test/unit/hub-create-session-umbrella.spec.ts","../test/unit/hub-gateway-create-appium-server.spec.ts","../test/unit/hub-node-control-forward.spec.ts","../test/unit/hub-node-gateway-appium-server.spec.ts","../test/unit/hub-node-race.spec.ts","../test/unit/hub-node-same-host.spec.ts","../test/unit/hub-register-removal.spec.ts","../test/unit/hub-remote-session-heartbeat.spec.ts","../test/unit/hub-routed-session-recovery.spec.ts","../test/unit/hub-session-token.spec.ts","../test/unit/insert-before-routes.spec.ts","../test/unit/inspector-hierarchy.spec.ts","../test/unit/install-repository-app-team.spec.ts","../test/unit/internal-call.spec.ts","../test/unit/ios-discovery-same-host.spec.ts","../test/unit/ios-idle-hold.spec.ts","../test/unit/ios-stream-appium-tunnel.spec.ts","../test/unit/ios-stream-port-leases.spec.ts","../test/unit/ios-stream-port.spec.ts","../test/unit/ios-tunnel-process.spec.ts","../test/unit/ios-wda-status-identity.spec.ts","../test/unit/iosBattery.spec.ts","../test/unit/iosStreamDiagnostics.spec.ts","../test/unit/is-xenon-running.spec.ts","../test/unit/logcat-multiplexer.spec.ts","../test/unit/logcat-parse.spec.ts","../test/unit/logcat-stream-service.spec.ts","../test/unit/logcat-ws.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/loopback-request.spec.ts","../test/unit/manualLock.test.ts","../test/unit/mark-node-busy-loki.spec.ts","../test/unit/mjpeg-proxy-cache.spec.ts","../test/unit/network-addresses.test.ts","../test/unit/node-create-caps.spec.ts","../test/unit/node-gateway-create-appium-server.spec.ts","../test/unit/node-hub-session-owner.spec.ts","../test/unit/node-phone-control.spec.ts","../test/unit/node-socket-relay.spec.ts","../test/unit/normalize-eol.spec.js","../test/unit/omni-vision.spec.ts","../test/unit/ostrace-parse.spec.ts","../test/unit/package-resolver.spec.ts","../test/unit/passwordResetMode.test.ts","../test/unit/plugin.spec.ts","../test/unit/port-allocator-os-probe.spec.ts","../test/unit/port-exhaustion.spec.ts","../test/unit/prisma.spec.ts","../test/unit/probe-duration.spec.ts","../test/unit/profile-router.test.ts","../test/unit/profileIdentity.spec.ts","../test/unit/proof-bundle.spec.ts","../test/unit/queue-requester.spec.ts","../test/unit/queue-team-scope-routes.spec.ts","../test/unit/queue-visibility.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-cleanup.spec.ts","../test/unit/recording-downloads-visibility.spec.ts","../test/unit/recording-files.spec.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-requests.spec.ts","../test/unit/recording-source-ended.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/recording-summary.spec.ts","../test/unit/recording-timing.spec.ts","../test/unit/recordings-library-routes.spec.ts","../test/unit/recordings-write-visibility.spec.ts","../test/unit/remote-session-create.spec.ts","../test/unit/remux-to-standard-mp4.spec.ts","../test/unit/reservation-team-visibility.spec.ts","../test/unit/reset-link.test.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/schema-required-args.spec.ts","../test/unit/scrcpy-server-session.spec.ts","../test/unit/scrcpy-version.spec.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/session-app-resolution.spec.ts","../test/unit/session-assets.spec.ts","../test/unit/session-attribution-wiring.spec.ts","../test/unit/session-create-layer.spec.ts","../test/unit/session-credential-strip.spec.ts","../test/unit/session-credentials.spec.ts","../test/unit/session-identity.spec.ts","../test/unit/session-listing-auth.spec.ts","../test/unit/session-locator.spec.ts","../test/unit/session-node-calls.spec.ts","../test/unit/session-owner-resolver.spec.ts","../test/unit/session-recovery-routing.spec.ts","../test/unit/session-upgrade-guard.spec.ts","../test/unit/session-visibility.spec.ts","../test/unit/shutdown-drain-remote.spec.ts","../test/unit/shutdown-sync-nets.spec.ts","../test/unit/single-flight.spec.ts","../test/unit/socket-team-scope.integration.spec.ts","../test/unit/socketServer.bearer.spec.ts","../test/unit/socketServer.scopedEmit.spec.ts","../test/unit/socketServer.sessionCookie.spec.ts","../test/unit/stored-session-capabilities.spec.ts","../test/unit/stream-leave-route.spec.ts","../test/unit/stream-leave.spec.ts","../test/unit/stream-own-device-row.spec.ts","../test/unit/stream-start-conflict.spec.ts","../test/unit/stream-status-type.spec.ts","../test/unit/stream-stop-ownership.spec.ts","../test/unit/stream-stop-recording.spec.ts","../test/unit/stream-ticket-identity.spec.ts","../test/unit/stream-watchdog-timers.spec.ts","../test/unit/sync-dir.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/upgrade-router.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/verify-credential.spec.ts","../test/unit/verify-locator.spec.ts","../test/unit/video-pipeline-args.spec.ts","../test/unit/video-pipeline-exit.spec.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/wda-cap-injection.spec.ts","../test/unit/webdriver-info-route.spec.ts","../test/unit/ws-upgrade-routing-appium-server.spec.ts","../test/unit/xenon-options.spec.ts","../test/unit/bug-report/archive.spec.ts","../test/unit/bug-report/har-collector.spec.ts","../test/unit/bug-report/manifest.spec.ts","../test/unit/bug-report/readme.spec.ts","../test/unit/bug-report/route.spec.ts","../test/unit/bug-report/service.spec.ts","../test/unit/bug-report/video-slice.spec.ts","../test/unit/bug-report/window.spec.ts","../test/unit/fixtures/device.config.js","../test/unit/fixtures/devices.js","../test/unit/interceptor/AndroidProxyAdapter.spec.ts","../test/unit/interceptor/CertManager.spec.ts","../test/unit/interceptor/HarBuilder.spec.ts","../test/unit/interceptor/HostFilter.spec.ts","../test/unit/interceptor/MitmProxyHost.spec.ts","../test/unit/interceptor/MockEngine.spec.ts","../test/unit/interceptor/RequestBuffer.spec.ts","../test/unit/interceptor/SessionArchive.spec.ts","../test/unit/lease/LeaseOrphanSweeper.spec.ts","../test/unit/lease/LeaseService.spec.ts","../test/unit/lease/allocate-lease-branch.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/lease-override.spec.ts","../test/unit/lease/lease-reap-held-phone.spec.ts","../test/unit/lease/lease-session-ownership.spec.ts","../test/unit/lease/lease-sweeper-expiry.spec.ts","../test/unit/lease/lease-team-visibility.spec.ts","../test/unit/lease/lease-token-log-filter.spec.ts","../test/unit/lease/lease-token-oracle.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/lease/nodePairAuth.spec.ts","../test/unit/lease/session-lease-proof.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenon-device-management/xenon",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Xenon - Intelligent Mobile Infrastructure. A self-healing device orchestration platform for Appium.",
5
5
  "main": "./lib/src/index.js",
6
6
  "exports": {
@@ -20,7 +20,7 @@
20
20
  "plugin:install": "appium plugin install --source=local $(pwd)",
21
21
  "plugin:reinstall": "export APPIUM_HOME=/tmp/xenon-home && (appium plugin uninstall xenon || exit 0) && npm run plugin:install",
22
22
  "test": "mocha",
23
- "test:all": "NODE_ENV=test mocha \"test/unit/**/*.{spec,test}.{ts,js}\" --plugin-xenon-platform=both",
23
+ "test:all": "NODE_ENV=test mocha --require test/setup/scratch-default-database.js \"test/unit/**/*.{spec,test}.{ts,js}\" --plugin-xenon-platform=both",
24
24
  "test:e2e": "mocha \"test/e2e/plugin.spec.*\" --timeout 300000",
25
25
  "test:e2e:hub": "mocha \"test/e2e/hubnode/*.spec.ts\" --plugin-xenon-platform=both --timeout 300000",
26
26
  "test:android": "mocha \"test/integration/androidDevices.spec.ts\"",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "repository": {
37
37
  "type": "git",
38
- "url": "https://github.com/Rabindra184/xenon"
38
+ "url": "git+https://github.com/Rabindra184/xenon.git"
39
39
  },
40
40
  "contributors": [
41
41
  {
@@ -89,7 +89,6 @@
89
89
  "get-port": "^5.1.1",
90
90
  "http-mitm-proxy": "^1.1.0",
91
91
  "http-proxy-agent": "7.0.0",
92
- "http-proxy-middleware": "^3.0.0-beta.1",
93
92
  "https-proxy-agent": "7.0.2",
94
93
  "ip": "^1.1.8",
95
94
  "jose": "^5.10.0",
@@ -0,0 +1,8 @@
1
+ -- AlterTable
2
+ ALTER TABLE "Device" ADD COLUMN "claimSessionId" TEXT;
3
+ ALTER TABLE "Device" ADD COLUMN "claimedAt" REAL;
4
+ ALTER TABLE "Device" ADD COLUMN "nodeBusy" BOOLEAN DEFAULT false;
5
+
6
+ -- CreateIndex
7
+ CREATE INDEX "Device_claimSessionId_idx" ON "Device"("claimSessionId");
8
+
@@ -196,10 +196,19 @@ model Device {
196
196
  lockedAt Float? @map("locked_at")
197
197
  teamId String?
198
198
  team Team? @relation(fields: [teamId], references: [id])
199
+ // This server's claim on the phone for a session: when it was taken, and
200
+ // the session's id once the session exists (null while it is created).
201
+ // See src/data-service/deviceClaims.ts.
202
+ claimSessionId String?
203
+ claimedAt Float?
204
+ // On a hub, what the phone's node last reported: busy there. `busy` is the
205
+ // claim OR this. Always false for a phone this server drives.
206
+ nodeBusy Boolean? @default(false)
199
207
 
200
208
  @@id([udid, host])
201
209
  @@index([owningSessionId])
202
210
  @@index([teamId])
211
+ @@index([claimSessionId])
203
212
  }
204
213
 
205
214
  model PendingSession {
@@ -1,10 +0,0 @@
1
- import{c as m,j as o,r as f,t as g,f as b}from"./index-BR1wTIPC.js";/**
2
- * @license lucide-react v0.555.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const x=[["path",{d:"M12 20v-9",key:"1qisl0"}],["path",{d:"M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z",key:"uouzyp"}],["path",{d:"M14.12 3.88 16 2",key:"qol33r"}],["path",{d:"M21 21a4 4 0 0 0-3.81-4",key:"1b0z45"}],["path",{d:"M21 5a4 4 0 0 1-3.55 3.97",key:"5cxbf6"}],["path",{d:"M22 13h-4",key:"1jl80f"}],["path",{d:"M3 21a4 4 0 0 1 3.81-4",key:"1fjd4g"}],["path",{d:"M3 5a4 4 0 0 0 3.55 3.97",key:"1d7oge"}],["path",{d:"M6 13H2",key:"82j7cp"}],["path",{d:"m8 2 1.88 1.88",key:"fmnt4t"}],["path",{d:"M9 7.13V6a3 3 0 1 1 6 0v1.13",key:"1vgav8"}]],h=m("bug",x),v=({tone:e="neutral",children:r,title:s})=>o.jsx("span",{className:`pill pill-${e}`,title:s,children:r});async function y(e){const r=new URLSearchParams({mode:e.mode});e.mode==="slice"&&e.windowSec&&r.set("windowSec",String(e.windowSec));const s=`/xenon/api/sessions/${encodeURIComponent(e.sessionId)}/bug-report?${r.toString()}`,t=await fetch(s,{method:"POST"});if(!t.ok){let u=`HTTP ${t.status}`;try{const p=await t.json();p&&p.error&&(u=p.error)}catch{}throw new Error(u)}const a=t.headers.get("content-disposition")||"",n=/filename="([^"]+)"/.exec(a),c=n?n[1]:`bugreport-${e.sessionId}.zip`,d=await t.blob(),l=URL.createObjectURL(d),i=document.createElement("a");i.href=l,i.download=c,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(l)}const j=({sessionId:e,mode:r,windowSec:s,variant:t})=>{const[a,n]=f.useState(!1),{toast:c}=g();async function d(){if(!a){n(!0);try{await y({sessionId:e,mode:r,windowSec:s}),c("Bug report downloaded","success")}catch(l){c(`Bug report failed: ${l.message}`,"error")}finally{n(!1)}}}return t==="floating"?o.jsxs("button",{type:"button",onClick:d,disabled:a,title:`Capture last ${s??60}s as bug report`,"aria-label":"Generate bug report",className:`fixed bottom-4 right-4 z-30 inline-flex items-center gap-2 px-3 py-2 rounded-full
7
- bg-[var(--surface-2)] border border-[var(--border)] text-xs text-[var(--text)]
8
- shadow-lg hover:bg-[var(--surface-raised)] disabled:opacity-50`,children:[a?o.jsx(b,{className:"h-3.5 w-3.5 animate-spin"}):o.jsx(h,{className:"h-3.5 w-3.5"}),"Bug report"]}):o.jsxs("button",{type:"button",onClick:d,disabled:a,title:"Download a zip of this session for ticketing",className:`inline-flex items-center gap-1.5 px-3 py-1.5 rounded text-xs
9
- bg-[var(--surface-2)] hover:bg-[var(--surface-raised)] border border-[var(--border)]
10
- text-[var(--text)] disabled:opacity-50`,children:[a?o.jsx(b,{className:"h-3.5 w-3.5 animate-spin"}):o.jsx(h,{className:"h-3.5 w-3.5"}),"Download bug report"]})};export{j as B,v as P};
@@ -1 +0,0 @@
1
- .dc2{position:relative;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);font-family:Inter,sans-serif;display:flex;flex-direction:column;transition:border-color var(--motion-fast),box-shadow var(--motion-fast)}.dc2:hover{border-color:var(--border-strong);box-shadow:var(--shadow-md)}.dc2-band{display:flex;justify-content:space-between;align-items:center;gap:10px;min-height:30px;padding:7px 12px;font-size:11px;font-weight:600;border-radius:var(--radius-md) var(--radius-md) 0 0}.dc2-band-label{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}.dc2-band-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.dc2-band-activity{min-width:0;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dc2-band-ready{background:var(--surface-2);color:var(--status-ready-fg)}.dc2-band-busy{background:var(--status-busy-bg);color:var(--status-busy-fg)}:root[data-theme=light] .dc2-band-busy{color:var(--text)}:root[data-theme=light] .dc2-band-busy .dc2-band-dot{background:var(--status-busy-fg)}.dc2-band-reserved{background:var(--status-reserved-bg);color:var(--blue-400)}:root[data-theme=light] .dc2-band-reserved{color:var(--status-reserved-fg)}.dc2-band-maintenance,.dc2-band-offline{background:var(--status-offline-bg);color:var(--status-offline-fg)}.dc2-body{flex:1;display:flex;flex-direction:column;gap:10px;padding:12px}.dc2-dim .dc2-icon,.dc2-dim .dc2-meta>:not(.dc2-tag){opacity:.55}.dc2-dim .dc2-title{color:var(--text-muted)}.dc2-head{display:flex;align-items:center;gap:12px;min-width:0}.dc2-icon{flex:none;width:44px;height:56px;border-radius:10px;background:var(--surface-2);color:var(--text-muted);display:flex;align-items:center;justify-content:center}.dc2-id{min-width:0}.dc2-title{color:var(--text);font-size:15px;font-weight:600;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dc2-subtitle{margin-top:2px;color:var(--text-muted);font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dc2-meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:20px}.dc2-tag{color:var(--text-dim);font-size:11px}.dc2-dim .dc2-tag{color:var(--status-offline-tag)}.dc2-foot{display:flex;align-items:center;gap:6px;padding:10px 12px;border-top:1px solid var(--border)}.dc2-spacer{flex:1}.dc2-unavailable{min-width:0;margin:0;color:var(--text-dim);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dc2-health{display:flex;gap:6px;flex-wrap:wrap}.reservation-modal-body{display:flex;flex-direction:column;gap:20px}.reservation-modal-body p{color:var(--text-dim);font-size:13px;line-height:1.6;margin:0}.device-id-badge{display:inline-flex;align-items:center;gap:8px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));padding:8px 16px;border-radius:6px;border:1px solid var(--border);font-family:JetBrains Mono,monospace;font-size:11px;width:fit-content;margin-bottom:12px}.reservation-input{width:100%;background-color:rgb(var(--rgb-well) / calc(.3 * var(--well-k)));border:1px solid var(--border);border-radius:6px;padding:12px 16px;color:var(--text);font-size:13px;box-sizing:border-box;transition:all .2s;font-family:JetBrains Mono,monospace}.reservation-input:focus{outline:none;border-color:var(--color-accent);box-shadow:none}.duration-selector{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:8px}.duration-option{background-color:rgb(var(--rgb-well) / calc(.3 * var(--well-k)));border:1px solid var(--border);color:var(--text-dim);padding:10px;border-radius:6px;font-size:11px;cursor:pointer;text-align:center;transition:all .2s;font-weight:800;font-family:JetBrains Mono,monospace}.duration-option:hover{border-color:var(--text-muted);background-color:rgb(var(--rgb-fg) / .02)}.duration-option.active{background-color:rgb(var(--rgb-accent) / .05);border-color:var(--color-accent);color:var(--color-accent);box-shadow:none}.btn-cancel{background:transparent;border:1px solid var(--border);color:var(--text-dim);padding:10px 24px;border-radius:6px;font-size:12px;font-weight:700;cursor:pointer;transition:all .2s}.btn-reserve{background:var(--color-accent);color:var(--bg);border:none;padding:10px 24px;border-radius:6px;font-size:12px;font-weight:800;cursor:pointer;transition:all .2s;box-shadow:none}.btn-reserve:hover:not(:disabled){background:var(--color-accent);box-shadow:none}.btn-reserve:disabled{background-color:var(--border);color:var(--text-dim);cursor:not-allowed;box-shadow:none;filter:grayscale(1);opacity:.5}.title-icon{color:var(--color-accent)}.tag-modal-body{display:flex;flex-direction:column;gap:20px}.device-id-badge{display:inline-flex;align-items:center;gap:8px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));padding:8px 16px;border-radius:6px;border:1px solid var(--border);font-family:JetBrains Mono,monospace;font-size:11px}.device-id-badge .label{color:var(--text-dim);font-weight:800;font-size:11px}.device-id-badge .value{color:var(--color-accent);font-weight:800}.tags-display-section label{display:block;font-size:11px;font-weight:800;color:var(--text-dim);margin-bottom:8px}.input-with-button{display:flex;gap:8px}.input-with-button input{flex:1;background:rgb(var(--rgb-well) / calc(.3 * var(--well-k)));border:1px solid var(--border);border-radius:6px;padding:10px 14px;color:var(--text);font-size:13px;transition:all .2s;font-family:JetBrains Mono,monospace}.input-with-button input:focus{outline:none;border-color:var(--color-accent);box-shadow:none}.add-inline-btn{background:var(--color-accent);color:var(--bg);border:none;border-radius:6px;width:40px;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s}.add-inline-btn:hover:not(:disabled){background:var(--color-accent);box-shadow:none}.add-inline-btn:disabled{background:var(--border);color:var(--text-dim);cursor:not-allowed;filter:grayscale(1);opacity:.5}.tags-list{display:flex;flex-wrap:wrap;gap:8px;min-height:48px;padding:12px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border-radius:6px;border:1px dashed var(--border)}.tag-pill-editable{display:flex;align-items:center;gap:6px;background:rgb(var(--rgb-accent) / .05);color:var(--color-accent);padding:6px 12px;border-radius:6px;font-size:11px;font-weight:800;border:1px solid rgb(var(--rgb-accent) / .3);box-shadow:none}.remove-tag{background:transparent;border:none;color:var(--color-accent);cursor:pointer;padding:2px;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:all .2s;opacity:.7}.remove-tag:hover{background:rgb(var(--rgb-accent) / .2);opacity:1}.btn-cancel{padding:10px 24px;border-radius:6px;background:transparent;border:1px solid var(--border);color:var(--text-dim);font-weight:700;cursor:pointer;transition:all .2s;font-size:12px}.btn-cancel:hover{color:var(--text);border-color:var(--text-muted)}.btn-save{padding:10px 24px;border-radius:6px;background:var(--color-accent);border:none;color:var(--bg);font-weight:800;cursor:pointer;transition:all .2s;box-shadow:none;font-size:12px}.btn-save:hover:not(:disabled){background:var(--color-accent);box-shadow:none}.btn-save:disabled{background-color:var(--border);color:var(--text-dim);cursor:not-allowed;box-shadow:none;filter:grayscale(1);opacity:.5}.dc2-more{flex:none;background:transparent;border:1px solid var(--border);color:var(--text-muted);border-radius:var(--radius-md);width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background var(--motion-fast),color var(--motion-fast)}.dc2-more:hover{background:var(--surface-2);color:var(--text)}.device-explorer-card-container{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px;padding:16px;flex:1}.device-explorer-card-container::-webkit-scrollbar{width:6px}.device-explorer-card-container::-webkit-scrollbar-thumb{background:var(--border);border-radius:8px}.devtable.tbl{table-layout:fixed;width:100%}.devtable-col-status{width:150px}.devtable-col-platform{width:120px}.devtable-col-type{width:80px}.devtable-col-team{width:120px}.devtable-col-tags,.devtable-col-host{width:150px}.devtable-col-actions{width:220px}.devtable.tbl thead th,.devtable.tbl tbody td,.devtable.tbl tbody th.devtable-rowheader{padding:8px 12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.devtable.tbl tbody td,.devtable.tbl tbody th.devtable-rowheader{padding-top:5px;padding-bottom:5px}.devtable.tbl tbody th.devtable-rowheader{font-weight:400;text-align:left;vertical-align:middle;color:var(--text);border-bottom:1px solid var(--border)}.devtable.tbl tbody tr:last-child th.devtable-rowheader{border-bottom:none}.devtable.tbl th:first-child,.devtable.tbl td:first-child{padding-left:20px}.devtable.tbl th:last-child,.devtable.tbl td:last-child{padding-right:20px}.devtable.tbl tbody td.devtable-actions{white-space:normal;overflow:visible;text-overflow:clip;vertical-align:middle}.devtable.tbl thead th{position:sticky;top:var(--de2-sticky-h, 0px);background:var(--surface);z-index:1}.devtable-line{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.devtable-muted{color:var(--text-muted);font-size:11px}.devtable-row.is-offline .devtable-status-dot{opacity:.55}.devtable-row.is-offline .devtable-title{color:var(--text-muted)}.devtable-sort{display:inline-flex;align-items:center;gap:4px;background:none;border:none;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer}.devtable-sort:focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:1px}.devtable-tag{display:inline-block;margin-right:4px;color:var(--text-muted);font-size:11px}.devtable-row.is-offline .devtable-tag{color:var(--status-offline-tag)}.devtable-actions-inner{display:flex;align-items:center;gap:6px}.device-explorer-container{display:flex;flex-direction:column;width:100%;gap:var(--space-4)}.device-explorer-header-container{display:flex;align-items:center;justify-content:space-between;padding:4px 24px;background:#0f0f1ae6;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border-bottom:2px solid var(--border);position:sticky;top:0;z-index:15;gap:var(--space-8);flex-wrap:nowrap;box-shadow:0 10px 30px rgb(var(--rgb-black) / calc(.4 * var(--shadow-k)))}.device-explorer-header-left-container{display:flex;align-items:center;gap:24px;flex:1;min-width:0}.device-explorer-header-entry{display:flex;flex-direction:column;gap:4px;min-width:0}.device-explorer-header-entry-header{font-size:11px;font-weight:700;color:var(--text-dim)}.device-explorer-header-value{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.device-explorer-header-value>.device-explorer-header__platform-btn+.device-explorer-header__platform-btn{margin-left:4px}.device-explorer-header__platform-btn,.device-explorer-header__device-state{display:flex;align-items:center;gap:6px;padding:6px 12px;border-radius:6px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border:1px solid var(--border);color:var(--text-muted);font-size:12px;font-weight:600;cursor:pointer;transition:all .2s ease}.device-explorer-header__platform-btn:hover,.device-explorer-header__device-state:hover{background:rgb(var(--rgb-fg) / .03);color:var(--text);border-color:var(--border)}.device-explorer-header__platform-btn.selected,.device-explorer-header__device-state.selected{background:rgb(var(--rgb-accent) / .05);color:var(--color-accent);border-color:rgb(var(--rgb-accent) / .3);box-shadow:none}.device-explorer-header__device-state.ready.selected{border-color:var(--color-success);box-shadow:none}.device-explorer-header__device-state.busy.selected{background:rgb(var(--rgb-amber-alt) / .05);color:var(--status-busy-fg);border-color:rgb(var(--rgb-amber-alt) / .3);box-shadow:none}.device-explorer-header__device-state.offline.selected{background:#4a4a6a1a;color:var(--text-dim);border-color:var(--text-dim)}.device-explorer-search-wrapper{position:relative;width:320px}.device-explorer-search-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);pointer-events:none;opacity:.5}.device-explorer-header-text-filter{width:100%;height:32px;padding:0 12px 0 36px;border-radius:6px;border:1px solid var(--border);background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));font-family:JetBrains Mono,monospace;font-size:12px;color:var(--text);transition:all .2s ease}.device-explorer-header-text-filter:focus{outline:none;border-color:var(--color-accent);background:rgb(var(--rgb-well) / calc(.6 * var(--well-k)));box-shadow:none}.device-explorer-header-text-filter::placeholder{color:var(--text-dim);font-size:11px}.device-explorer-header-right-container{display:flex;align-items:center;gap:12px}.device-explorer-header-filter-count{display:flex;align-items:center;gap:8px;padding-right:16px;border-right:1px solid var(--border)}@media (max-width: 1024px){.device-explorer-header-container{flex-direction:column;align-items:stretch;gap:var(--space-4);padding:var(--space-4)}.device-explorer-header-left-container{flex-wrap:wrap;gap:var(--space-4)}.device-explorer-header-entry{flex:1;min-width:120px}.device-explorer-search-wrapper{width:100%}.device-explorer-header-right-container{justify-content:space-between;width:100%}}@media (max-width: 640px){.device-explorer-header-left-container{display:flex;flex-direction:column;align-items:stretch;gap:var(--space-3)}.device-explorer-header-entry,.device-explorer-header-value,.device-explorer-header-filter-count{width:100%;min-width:0}.device-explorer-header-filter-count{padding-right:0;border-right:none;justify-content:flex-start}.device-explorer-header-right-container{flex-direction:row;flex-wrap:wrap;align-items:center;gap:var(--space-2);width:100%}}.device-explorer-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:80px 40px;background:#0f0f1a66;border:1px dashed var(--border);border-radius:var(--radius-md);text-align:center;margin:60px auto 40px;max-width:600px;gap:var(--space-4)}.device-explorer-empty-icon{width:64px;height:64px;background:rgb(var(--rgb-accent) / .05);border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--color-accent);margin-bottom:8px;border:1px solid rgb(var(--rgb-accent) / .1)}.device-explorer-empty h3{font-size:1.5rem;font-weight:700;color:var(--text);margin:0;font-family:Outfit,sans-serif}.device-explorer-empty p{color:var(--text-muted);font-size:14px;max-width:400px;line-height:1.6;margin:0}.device-explorer-empty .Button{margin-top:8px}.device-control-modal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--bg);z-index:6000;display:flex;flex-direction:column;padding:0;margin:0;animation:modal-fade-in .25s ease-out}.device-control-modal{flex:1;width:100%;height:100%;overflow:hidden;display:flex;flex-direction:column;background:var(--bg)}@keyframes modal-fade-in{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.de2-sticky-group{position:sticky;top:0;z-index:15;background:var(--bg);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);box-shadow:0 6px 16px -8px rgb(var(--rgb-black) / calc(.5 * var(--shadow-k)))}.de2-toolbar{display:flex;gap:10px;align-items:center;padding:12px 20px;border-bottom:1px solid var(--border);background:transparent;box-shadow:none;flex-wrap:wrap}.de2-toolbar-row{flex:1 1 100%;display:flex;align-items:center;gap:10px;flex-wrap:wrap;min-width:0}.de2-search-wrap{position:relative;display:flex;align-items:center;flex:0 1 320px;min-width:200px}.de2-search-icon{position:absolute;left:9px;color:var(--text-dim);pointer-events:none}.de2-key{position:absolute;right:7px;padding:0 5px;border:1px solid var(--border);border-radius:4px;color:var(--text-dim);font-family:JetBrains Mono,ui-monospace,monospace;font-size:10px;line-height:16px;pointer-events:none}.de2-result .btn-base.btn-size-icon{width:28px;height:28px}.de2-result{margin-left:auto;display:flex;align-items:center;gap:10px;color:var(--text-muted);font-size:12px;white-space:nowrap}.de2-search{width:100%;height:28px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);padding:0 28px;color:var(--text);font-family:Inter,sans-serif;font-size:12px;outline:none}.de2-search::placeholder{color:var(--text-dim)}.de2-search:focus{border-color:var(--border-strong)}.device-explorer-empty h3{color:var(--text);font-family:Inter,sans-serif;font-weight:700;letter-spacing:-.01em}:root[data-theme=light] .device-explorer-header-container{background:rgb(var(--rgb-white) / .9)}:root[data-theme=light] .device-explorer-empty{background:var(--surface-2)}.device-control-view{display:flex;flex-direction:column;height:100%;width:100%;background:var(--bg);color:var(--text);overflow:hidden;font-family:Inter,sans-serif}*{scrollbar-width:thin;scrollbar-color:var(--border) transparent}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:8px;-webkit-transition:background .2s;transition:background .2s}::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}.control-view-top-bar{display:flex;align-items:center;padding:0 24px;height:64px;background:var(--surface);border-bottom:2px solid var(--border);gap:24px;z-index:100;position:relative}.device-info-mini{display:flex;align-items:center;gap:16px}.device-pill{font-size:11px;font-weight:800;padding:2px 10px;border-radius:6px}.platform-pill{background:rgb(var(--rgb-accent) / .05);color:var(--color-accent);border:1px solid rgb(var(--rgb-accent) / .2)}.version-pill{background:rgb(var(--rgb-amber-alt) / .05);color:var(--status-busy-fg);border:1px solid rgb(var(--rgb-amber-alt) / .2)}.reserved-pill{background:rgb(var(--rgb-sky-400) / .1);color:var(--sky-400);border:1px solid rgb(var(--rgb-sky-400) / .3);animation:pulse-reserved-pill 2s infinite ease-in-out}.device-name-text{font-family:Outfit,sans-serif;font-weight:800;font-size:14px;color:var(--text)}.code-font{font-family:JetBrains Mono,monospace;font-size:11px;color:var(--text-dim);background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));padding:4px 10px;border-radius:6px;border:1px solid var(--border)}.udid-chip{display:inline-flex;align-items:center;gap:6px;padding:3px 4px 3px 10px;font-family:JetBrains Mono,monospace;font-size:11px;color:var(--text-dim);background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border-radius:6px;border:1px solid var(--border);max-width:280px}.udid-chip__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.udid-chip__copy{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:transparent;border-radius:4px;color:var(--text-muted);cursor:pointer;transition:background .15s,color .15s;flex-shrink:0}.udid-chip__copy:hover{background:rgb(var(--rgb-fg) / .05);color:var(--color-accent)}.back-to-devices-btn{background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));color:var(--text-dim);border:1px solid var(--border);padding:8px 16px;border-radius:6px;font-size:11px;font-weight:800;display:flex;align-items:center;gap:8px;transition:all .2s;cursor:pointer}.back-to-devices-btn:hover{background:rgb(var(--rgb-fg) / .03);border-color:var(--color-accent);color:var(--color-accent)}.control-view-main{display:flex;flex-direction:row;flex:1;overflow:hidden;padding:24px;gap:32px;background:var(--bg);justify-content:center;align-items:stretch;min-height:0}.control-view-main.is-landscape{align-items:flex-start}.control-view-main.omni-mode{gap:20px}.control-view-main.omni-mode .device-preview-column{min-width:0;flex-shrink:1}.control-view-main.omni-mode .device-stream-canvas{max-width:100%;max-height:100%}.device-preview-column{display:flex;flex-direction:row-reverse;align-items:center;justify-content:center;gap:24px;flex-shrink:1;min-width:0;max-width:42%}.control-view-main.is-landscape .device-preview-column{max-width:none;flex-direction:column}.device-screen-wrapper{position:relative;padding:12px;background:var(--black);border-radius:48px;box-shadow:0 0 0 2px #334155,0 20px 50px rgb(var(--rgb-black) / calc(.6 * var(--shadow-k)));border:1px solid rgb(var(--rgb-white) / .1);transition:all .5s cubic-bezier(.16,1,.3,1)}.device-screen-wrapper:hover{transform:translateY(-4px) scale(1.005);box-shadow:0 0 0 2px var(--color-accent),0 30px 60px rgb(var(--rgb-black) / calc(.8 * var(--shadow-k)))}.device-stream-canvas{position:relative;background:var(--black);border-radius:28px;overflow:hidden;cursor:crosshair;transition:box-shadow .3s ease,border-color .3s ease;outline:none;border:2px solid transparent;user-select:none;-webkit-user-select:none}.device-stream-canvas.focused{border-color:var(--color-accent);box-shadow:none}.device-stream-image{pointer-events:none;-webkit-user-select:none;user-select:none;-webkit-user-drag:none}.device-stream-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;width:100%;color:var(--text-muted);gap:16px;background:radial-gradient(circle at center,var(--surface) 0%,var(--bg) 100%)}.device-screen-off{position:absolute;top:0;right:0;bottom:0;left:0;z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:16px;text-align:center;color:var(--text-muted);background:rgb(var(--rgb-black) / .55);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.device-screen-off p{margin:6px 0 0;font-size:13px;font-weight:600;color:var(--text)}.device-screen-off span{font-size:11px;line-height:1.5;opacity:.75;max-width:220px}.device-screen-off button{margin-top:10px}.device-footer-actions{display:flex;flex-direction:column;flex-wrap:wrap;align-content:center;justify-content:center;width:auto;flex-shrink:0;background:color-mix(in srgb,var(--surface-2) 80%,transparent);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:16px;border:1px solid rgb(var(--rgb-fg) / .08);padding:6px;gap:6px;box-shadow:0 10px 25px -5px rgb(var(--rgb-black) / calc(.4 * var(--shadow-k)))}.footer-action-btn{flex:0 0 auto;display:flex;align-items:center;justify-content:center;gap:8px;width:36px;height:36px;padding:0;color:var(--text-muted);font-size:11px;font-weight:700;border:none;background:transparent;border-radius:var(--radius-sm);transition:all .2s ease}.footer-action-btn:hover{background:rgb(var(--rgb-fg) / .05);color:var(--text)}.footer-action-btn.active{background:rgb(var(--rgb-fg) / .04);color:var(--color-accent);box-shadow:inset 0 -2px 0 0 var(--color-accent)}.footer-divider{width:24px;height:1px;background:var(--border);margin:4px auto;flex-shrink:0}.control-view-main.is-landscape .device-footer-actions{flex-direction:row;width:100%}.control-view-main.is-landscape .footer-divider{width:1px;height:24px;margin:auto 4px}.hint-text{display:block;font-size:11px;color:var(--text-muted);font-style:italic;margin-top:4px}.device-interactions-column{flex:1;display:flex;flex-direction:column;gap:0;min-width:450px;max-width:1200px;height:100%;overflow:hidden;min-height:0}.interaction-tabs{display:flex;gap:4px;background:var(--surface);padding:4px;border-radius:6px;border:1px solid var(--border);margin-bottom:16px;flex-shrink:0}.tab-btn{flex:1 1 0;min-width:0;display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:8px 6px;background:transparent;border:none;font-size:11px;font-weight:800;color:var(--text-dim);border-radius:4px;cursor:pointer;transition:all .2s;white-space:nowrap}.tab-btn>svg{flex-shrink:0;opacity:.7;transition:opacity .15s}.tab-btn>span{min-width:0;overflow:hidden;text-overflow:ellipsis}.tab-btn:hover>svg,.tab-btn.active>svg{opacity:1}.tab-btn:hover{color:var(--text);background:rgb(var(--rgb-fg) / .02)}.tab-btn.active{color:var(--bg);background:var(--color-accent);box-shadow:none}.interactions-scroll-area{flex:1;overflow-y:auto;overflow-x:hidden;padding-right:8px;display:flex;flex-direction:column}.action-card{background:rgb(var(--rgb-well) / calc(.2 * var(--well-k)));border-radius:6px;padding:20px;border:1px solid var(--border);transition:all .2s;display:flex;flex-direction:column;gap:16px}.action-card:hover{background:rgb(var(--rgb-fg) / .01);border-color:var(--color-accent);box-shadow:0 4px 20px rgb(var(--rgb-black) / calc(.4 * var(--shadow-k)))}.btn-sm{padding:8px 16px;font-size:11px}.type-input-field.compact{padding:10px;font-size:13px}.install-app-section,.uninstall-app-section{flex:1;display:flex;flex-direction:column;gap:12px;min-width:0}.btn-premium,.dc-btn-secondary{padding:10px 20px;border-radius:var(--radius-sm);font-weight:700;font-size:11px;cursor:pointer;transition:all .2s cubic-bezier(.16,1,.3,1);display:flex;align-items:center;justify-content:center;gap:8px;border:none}.btn-premium{background:var(--color-accent);color:var(--color-on-accent)}.btn-premium:hover:not(:disabled){background:var(--color-accent-strong);transform:translateY(-1px);box-shadow:none}.dc-btn-secondary{background:rgb(var(--rgb-fg) / .05);color:var(--text);border:1px solid var(--border)}.dc-btn-secondary:hover:not(:disabled){background:rgb(var(--rgb-fg) / .1);color:var(--text);border-color:var(--text-muted)}.dc-btn-secondary.active{background:var(--primary-soft);color:var(--color-accent);border-color:var(--color-accent)}.btn-sm{padding:6px 12px!important;font-size:11px!important}.type-input-field{width:100%;padding:10px 14px;border-radius:var(--radius-sm);border:1px solid var(--border);background:rgb(var(--rgb-well) / calc(.3 * var(--well-k)));font-size:13px;color:var(--text);transition:all .2s ease}.type-input-field::placeholder{color:var(--text-dim)}.type-input-field:focus{outline:none;border-color:var(--color-accent);background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));box-shadow:0 0 0 3px var(--primary-soft)}.animate-pulse{animation:pulse-op 1.5s infinite}@keyframes pulse-op{0%,to{opacity:1}50%{opacity:.4}}.tab-content{animation:slideUpFade .4s cubic-bezier(.16,1,.3,1);display:flex;flex-direction:column;flex:1;min-height:0}@keyframes slideUpFade{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.btn-destructive{background:var(--status-error-fg);color:var(--white);border:1px solid transparent;padding:10px 20px;border-radius:var(--radius-sm);font-weight:700;font-size:11px;display:flex;align-items:center;gap:8px;cursor:pointer;transition:background .2s ease,transform .2s ease,box-shadow .2s ease}.btn-destructive:hover:not(:disabled){background:var(--red-600);transform:translateY(-1px);box-shadow:none}.btn-destructive:disabled{opacity:.5;cursor:not-allowed}.type-input-field.tiny{padding:8px 12px;font-size:12px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.action-card-header{display:flex;justify-content:flex-end;align-items:flex-start;margin-bottom:12px}.screenshot-workspace{display:flex;gap:20px;flex:1;min-height:0;overflow:hidden}.screenshot-gallery-sidebar{width:180px;display:flex;flex-direction:column;gap:16px;flex-shrink:0;min-height:0}.screenshot-workspace.is-empty .screenshot-main-preview{display:none}.screenshot-workspace.is-empty .screenshot-gallery-sidebar{width:100%;align-items:center;justify-content:center;gap:24px}.screenshot-workspace.is-empty .screenshot-thumbnails-list{order:1;flex:none;overflow:visible}.screenshot-workspace.is-empty .take-screenshot-btn{order:2;width:auto;min-width:200px;flex:none}.take-screenshot-btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%}.screenshot-thumbnails-list{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:10px;padding-right:4px;min-height:0}.screenshot-thumb-item{position:relative;border-radius:8px;overflow:hidden;aspect-ratio:9/16;background:rgb(var(--rgb-black) / .4);border:2px solid transparent;cursor:pointer;transition:all .2s ease;flex-shrink:0}.screenshot-thumb-item:hover{border-color:rgb(var(--rgb-accent) / .4)}.screenshot-thumb-item.active{border-color:var(--color-accent);box-shadow:none}.screenshot-thumb-item img{width:100%;height:100%;object-fit:cover;opacity:.7;transition:opacity .2s ease}.screenshot-thumb-item:hover img,.screenshot-thumb-item.active img{opacity:1}.thumb-time{position:absolute;bottom:0;left:0;right:0;background:rgb(var(--rgb-black) / .7);color:#fff;font-size:11px;padding:2px 4px;text-align:center;font-family:JetBrains Mono,monospace}.thumb-delete-btn{position:absolute;top:4px;right:4px;width:20px;height:20px;border-radius:4px;background:rgb(var(--rgb-red) / .8);color:#fff;border:none;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .2s ease}.screenshot-thumb-item:hover .thumb-delete-btn{opacity:1}.thumb-delete-btn:hover{background:var(--status-error-fg)}.screenshot-main-preview{flex:1;background:rgb(var(--rgb-black) / .3);border-radius:8px;display:flex;align-items:center;justify-content:center;overflow:hidden;position:relative;border:1px solid rgb(var(--rgb-white) / .05);min-height:0}.preview-container{display:flex;flex-direction:column;width:100%;height:100%;position:relative}.preview-image-wrapper{flex:1;position:relative;min-height:0}.preview-image-wrapper img{position:absolute;top:20px;bottom:20px;left:20px;right:20px;max-width:calc(100% - 40px);max-height:calc(100% - 40px);object-fit:contain;margin:auto;border-radius:4px;box-shadow:0 10px 40px rgb(var(--rgb-black) / calc(.5 * var(--shadow-k)))}.preview-footer{padding:16px 24px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border-top:1px solid rgb(var(--rgb-fg) / .05);display:flex;justify-content:space-between;align-items:center}.preview-meta{display:flex;align-items:center;gap:8px;font-size:11px;color:var(--text-muted)}.meta-label{font-weight:700;opacity:.5}.meta-divider{opacity:.2}.preview-actions{display:flex;gap:12px}.btn-text-only{background:transparent;border:none;color:var(--text-muted);font-size:11px;font-weight:700;letter-spacing:.05em;cursor:pointer;padding:4px 8px;border-radius:4px}.btn-text-only:hover{color:var(--red);background:rgb(var(--rgb-red) / .05)}.empty-gallery-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:24px 12px;color:var(--text-muted);font-size:11px;text-align:center}.empty-gallery-icon{opacity:.4}.empty-gallery-title{font-weight:700;font-size:12px;color:var(--text);margin:0}.empty-gallery-hint{margin:0;font-size:11px;color:var(--text-muted);line-height:1.4;max-width:160px}.empty-gallery-hint strong{color:var(--color-accent);font-weight:700}.interactions-scroll-area.terminal-mode{overflow:hidden;padding:0;display:flex;flex-direction:column;height:100%;min-height:0}.omni-inspector-tab-wrapper{flex:1;min-height:0;display:flex;flex-direction:column}.interactions-scroll-area.terminal-mode .action-card.full-height{height:100%;min-height:0;border-radius:0;border:none}.interactions-scroll-area.screenshot-mode{overflow:hidden;height:100%;min-height:0;display:flex;flex-direction:column;padding:0}.interactions-scroll-area.screenshot-mode .tab-content{display:flex;flex-direction:column;flex:1 1 0%;min-height:0;padding:0}.interactions-scroll-area.screenshot-mode .action-card.screenshot-card{display:flex;flex-direction:column;flex:1;min-height:0;margin-bottom:0;border-radius:0;border:none;padding:0;overflow:hidden}@media (max-width: 900px){.control-view-main{flex-direction:column;padding:16px;gap:16px;overflow-y:auto}.device-preview-column{min-width:0;width:100%;max-width:420px;margin:0 auto}.device-interactions-column{width:100%;max-width:100%;min-width:0}}.device-stream-canvas.is-inspecting{cursor:crosshair}.terminal-container{display:flex;flex-direction:column;background-color:var(--bg);color:var(--text);font-family:JetBrains Mono,monospace;border-radius:6px;overflow:hidden;height:100%;max-height:100%;width:100%;min-height:0;border:1px solid var(--border);box-shadow:0 20px 50px rgb(var(--rgb-black) / calc(.5 * var(--shadow-k)));position:relative}.terminal-header{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;background-color:rgb(var(--rgb-black) / .4);border-bottom:2px solid var(--border)}.terminal-controls{display:flex;gap:8px;width:60px}.dot{width:8px;height:8px;border-radius:4px;border:1px solid rgb(var(--rgb-fg) / .1)}.dot.red{background-color:var(--red-alt)}.dot.yellow{background-color:#fc0}.dot.green{background-color:var(--color-accent)}.terminal-title{font-size:11px;font-weight:800;color:var(--text-dim)}.terminal-actions{display:flex;justify-content:flex-end;width:60px}.terminal-action-btn{background:transparent;border:1px solid var(--border);color:var(--text-dim);font-size:11px;font-weight:800;padding:4px 10px;border-radius:6px;cursor:pointer;transition:all .2s}.terminal-action-btn:hover{color:var(--text);background:rgb(var(--rgb-white) / .05);border-color:var(--text-muted)}.terminal-history{flex:1;overflow-y:auto;overflow-x:hidden;padding:20px;font-size:12px;line-height:1.6;scrollbar-width:thin;scrollbar-color:var(--color-accent) var(--bg);min-height:0}.terminal-history::-webkit-scrollbar{width:6px}.terminal-history::-webkit-scrollbar-track{background:transparent}.terminal-history::-webkit-scrollbar-thumb{background-color:var(--border);border-radius:4px}.terminal-history::-webkit-scrollbar-thumb:hover{background-color:var(--color-accent)}.terminal-line{margin-bottom:6px;white-space:pre-wrap;word-break:normal;overflow-wrap:anywhere}.terminal-line.command{color:var(--color-accent);font-weight:600}.terminal-line.output{color:var(--text)}.terminal-line.error{color:var(--red-alt)}.terminal-line.system{color:var(--text-dim);font-style:italic;border-bottom:1px dashed var(--border);padding-bottom:6px;margin-bottom:12px}.terminal-input-area{display:flex;align-items:center;padding:16px 20px;background-color:rgb(var(--rgb-black) / .4);border-top:2px solid var(--border)}.terminal-prompt{color:var(--color-accent);margin-right:12px;font-weight:800;-webkit-user-select:none;user-select:none}.terminal-input{flex:1;background:transparent;border:none;color:var(--text);font-family:inherit;font-size:13px;outline:none;font-weight:500}.terminal-input::placeholder{color:rgb(var(--rgb-white) / .1)}.terminal-loading-indicator{display:inline-block;width:8px;height:16px;background-color:var(--color-accent);animation:blink 1s step-end infinite;vertical-align:middle;margin-left:8px;border-radius:4px}@keyframes blink{0%,to{opacity:1}50%{opacity:0}}.omni-inspector-container{display:flex;flex-direction:column;height:100%;background:var(--bg);color:var(--text);font-family:Inter,sans-serif;overflow:hidden;position:relative}.omni-main-content{flex:1;display:flex;gap:16px;padding:16px;overflow:hidden;height:100%}.omni-screenshot-panel{width:380px;min-width:320px;flex-shrink:0;display:flex;flex-direction:column;background:var(--surface);border-radius:6px;border:1px solid var(--border);overflow:hidden}.omni-screenshot-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;background:rgb(var(--rgb-black) / .4);border-bottom:2px solid var(--border)}.omni-screenshot-title{font-size:11px;font-weight:800;color:var(--text);opacity:.9}.omni-mode-toggle{display:flex;background:rgb(var(--rgb-well) / calc(.3 * var(--well-k)));padding:2px;border-radius:6px;border:1px solid var(--border)}.omni-mode-btn{display:flex;align-items:center;gap:6px;padding:4px 10px;background:transparent;border:none;border-radius:4px;color:var(--text-dim);font-size:11px;font-weight:800;cursor:pointer;transition:all .2s}.omni-mode-btn.active{background:var(--color-accent);color:var(--bg);box-shadow:none}.omni-refresh-btn{display:flex;align-items:center;gap:6px;padding:6px 12px;background:var(--color-accent);color:var(--bg);border:none;border-radius:6px;font-size:11px;font-weight:800;cursor:pointer;transition:all .2s}.omni-refresh-btn:hover:not(:disabled){background:var(--color-accent);box-shadow:none}.omni-refresh-btn:disabled{opacity:.5;cursor:not-allowed}.omni-screenshot-container{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;padding:12px;background:#161b22b3;position:relative;overflow:hidden}.omni-screenshot-wrapper{position:relative;max-width:100%;max-height:100%;height:100%;display:flex;align-items:center;justify-content:center;-webkit-user-select:none;user-select:none}.omni-screenshot-wrapper.interactable{cursor:crosshair}.omni-screenshot-img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;border-radius:4px;display:block}.omni-overlay{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none}.omni-overlay>*{pointer-events:auto}.omni-hit-area{position:absolute;cursor:pointer;background:transparent;transition:background .15s ease}.omni-hit-area:hover{background:rgb(var(--rgb-accent) / .2)}.omni-frame-hover{position:absolute;border:2px solid var(--color-accent);background:rgb(var(--rgb-accent) / .1);pointer-events:none;border-radius:6px}.omni-frame-select{position:absolute;border:2px solid var(--color-accent);background:rgb(var(--rgb-accent) / .2);pointer-events:none;box-shadow:none;border-radius:6px}.omni-frame-match{position:absolute;pointer-events:none;border-radius:6px;border-style:dashed;border-width:2px;animation:omni-match-pulse 1.6s ease-out 1}.omni-frame-match.unique{border-color:var(--color-success);background:rgb(var(--rgb-success) / .12);box-shadow:none}.omni-frame-match.multi{border-color:var(--amber, var(--amber));background:rgb(var(--rgb-amber) / .1);box-shadow:none}@keyframes omni-match-pulse{0%{opacity:0;transform:scale(.96)}35%{opacity:1;transform:scale(1)}to{opacity:1;transform:scale(1)}}.omni-loading-overlay{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;background:rgb(var(--rgb-black) / .8);color:var(--text-muted);font-size:11px}.omni-spinner{width:24px;height:24px;border:2px solid var(--border);border-top-color:var(--color-accent);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.omni-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;color:var(--text-muted);text-align:center;padding:32px;font-size:12px}.omni-empty-state svg{opacity:.3}.omni-empty-state.small{padding:24px;font-size:11px}.omni-tree-panel{flex:1;min-width:0;display:flex;flex-direction:column;background:rgb(var(--rgb-well) / calc(.2 * var(--well-k)));border-radius:6px;border:1px solid var(--border);overflow:hidden;min-height:0}.omni-tree-content{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;padding:4px;scrollbar-width:thin;scrollbar-color:var(--border) transparent}.omni-tree-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;row-gap:8px;column-gap:8px;padding:12px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border-bottom:2px solid var(--border)}.omni-tree-title{display:flex;align-items:center;gap:8px;font-size:11px;font-weight:800;color:var(--text);opacity:.9}.omni-action-btn{display:flex;align-items:center;justify-content:center;width:28px;height:28px;background:rgb(var(--rgb-fg) / .02);border:1px solid var(--border);border-radius:6px;color:var(--text-dim);cursor:pointer;transition:all .2s}.omni-action-btn:hover{background:rgb(var(--rgb-fg) / .05);color:var(--color-accent);border-color:var(--color-accent)}.omni-tree-search{display:flex;align-items:center;gap:8px;margin:12px;padding:8px 12px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border:1px solid var(--border);border-radius:6px;transition:all .2s}.omni-tree-search:focus-within{border-color:var(--color-accent);box-shadow:none}.omni-tree-search input{flex:1;background:transparent;border:none;color:var(--text);font-size:11px;outline:none;font-family:JetBrains Mono,monospace}.omni-details-panel{flex:1;min-width:280px;max-width:360px;display:flex;flex-direction:column;background:var(--surface);border-radius:6px;border:1px solid var(--border);overflow:hidden;min-height:0}.omni-details-content{flex:1;min-height:0;overflow-y:auto;padding:16px;scrollbar-width:thin;scrollbar-color:var(--border) transparent}.omni-split{flex:1;display:flex;min-width:0;min-height:0}.omni-split>.omni-tree-panel{flex:0 0 auto;min-width:0}.omni-split>.omni-details-panel{flex:1 1 0;min-width:0;max-width:none}.omni-split-divider{position:relative;flex:0 0 12px;display:flex;align-items:center;justify-content:center;cursor:col-resize;touch-action:none;outline:none}.omni-split-divider:before{content:"";position:absolute;top:0;bottom:0;left:5px;width:2px;background:transparent}.omni-split-divider:hover:before,.omni-split-divider.is-dragging:before{background:var(--border-strong)}.omni-split-divider:focus-visible:before{background:var(--color-focus-ring)}.omni-split-divider__grip{position:relative;width:4px;height:28px;border-radius:2px;background:var(--text-dim)}.omni-split-divider:hover .omni-split-divider__grip,.omni-split-divider.is-dragging .omni-split-divider__grip{background:var(--text-muted)}@media (forced-colors: active){.omni-split-divider:before,.omni-split-divider:hover:before,.omni-split-divider.is-dragging:before,.omni-split-divider__grip,.omni-split-divider:hover .omni-split-divider__grip,.omni-split-divider.is-dragging .omni-split-divider__grip{background:CanvasText}.omni-split-divider:focus-visible:before{background:Highlight}}.omni-header-left{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.omni-tree-actions{display:flex;gap:6px;align-items:center;flex-shrink:0;margin-left:auto}.omni-clear-btn{background:transparent;border:none;color:var(--text-muted);cursor:pointer;font-size:16px;padding:0 4px;line-height:1;border-radius:3px}.omni-clear-btn:hover{color:var(--text);background:rgb(var(--rgb-fg) / .08)}.omni-info-table,.omni-locators-list{display:flex;flex-direction:column;gap:6px}.omni-details-header{display:flex;align-items:center;gap:8px;padding:12px 16px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border-bottom:2px solid var(--border);font-size:11px;font-weight:800;color:var(--text);opacity:.9}.omni-section{margin-bottom:24px}.omni-section-header{font-size:11px;font-weight:800;color:var(--text-dim);margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--border)}.omni-info-row{display:flex;gap:16px;padding:12px 16px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border-radius:6px;border:1px solid var(--border);min-height:44px;align-items:center}.omni-info-key{width:60px;flex-shrink:0;font-size:11px;font-weight:800;color:var(--text-dim)}.omni-info-value{flex:1;font-size:11px;color:var(--text);word-break:break-all}.omni-info-row--path{align-items:flex-start}.omni-crumbs{flex:1;min-width:0}.omni-crumbs ol{display:flex;flex-wrap:wrap;align-items:center;gap:2px 0;margin:0;padding:0;list-style:none;min-width:0}.omni-crumbs li{display:flex;align-items:center;min-width:0}.omni-crumbs li+li:before{content:"›";content:"›" / "";padding:0 4px;color:var(--text-dim)}.omni-crumb{max-width:16ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:1px 4px;border:0;border-radius:3px;background:transparent;font-family:JetBrains Mono,Fira Code,monospace;font-size:11px;color:var(--text-muted);cursor:pointer}.omni-crumb:hover{background:rgb(var(--rgb-fg) / .06);color:var(--text)}.omni-crumb:focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:1px}.omni-crumb.is-current{color:var(--text);font-weight:600;cursor:default}.omni-layout-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}.omni-layout-item{display:flex;flex-direction:column;gap:6px;padding:12px 8px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border-radius:6px;border:1px solid var(--border);text-align:center;min-height:60px;justify-content:center}.omni-layout-label{font-size:11px;font-weight:800;color:var(--text-dim)}.omni-layout-value{font-size:12px;font-weight:800;color:var(--color-accent);font-family:JetBrains Mono,monospace}.omni-locator-row{display:flex;align-items:center;gap:12px;padding:12px 16px;background:rgb(var(--rgb-well) / calc(.6 * var(--well-k)));border-radius:6px;border:1px solid var(--border);border-left:3px solid var(--color-accent);transition:all .2s;min-height:48px}.omni-locator-strategy{flex-shrink:0;font-size:11px;font-weight:800;background:rgb(var(--rgb-accent) / .05);color:var(--color-accent);padding:2px 6px;border-radius:6px}.omni-locator-value{flex:1;font-family:JetBrains Mono,monospace;font-size:11px;color:var(--text-muted);word-break:break-all;line-height:1.5}.omni-copy-btn{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:24px;height:24px;background:rgb(var(--rgb-fg) / .03);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text-muted);cursor:pointer;transition:all .2s ease}.omni-copy-btn:hover{background:var(--color-accent);border-color:var(--color-accent);color:var(--color-on-accent)}.omni-locator-actions{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}.omni-locators-note{display:flex;align-items:flex-start;gap:6px;margin:0 0 8px;padding:8px 10px;border:1px dashed var(--border-strong);border-radius:6px;font-size:11px;line-height:1.5;color:var(--text-muted)}.omni-locators-note>svg{flex-shrink:0;margin-top:2px}.omni-match-badge{display:inline-flex;align-items:center;gap:3px;padding:1px 6px;border-radius:4px;font-size:11px;font-weight:600;border:1px solid transparent;line-height:1.4;white-space:nowrap}.omni-match-badge.unique{background:rgb(var(--rgb-success) / .12);border-color:rgb(var(--rgb-success) / .4);color:var(--color-success)}.omni-match-badge.multi{background:rgb(var(--rgb-amber) / .12);border-color:rgb(var(--rgb-amber) / .4);color:var(--amber, var(--amber))}.omni-match-badge.zero{background:rgb(var(--rgb-red) / .12);border-color:rgb(var(--rgb-red) / .4);color:var(--red, var(--red))}.omni-match-badge.unsupported{background:rgb(var(--rgb-fg) / .04);border-color:var(--border);color:var(--text-dim)}.omni-copy-btn.copied{background:var(--color-accent);border-color:var(--color-accent);color:var(--color-on-accent)}.omni-attributes-table{display:flex;flex-direction:column;gap:4px;background:#161b22b3;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-radius:var(--radius-sm);border:1px solid var(--border);padding:8px;max-height:200px;overflow-y:auto}.omni-attr-row{display:flex;gap:8px;padding:6px 8px;border-radius:4px;transition:background .2s ease}.omni-attr-row:hover{background:rgb(var(--rgb-fg) / .03)}.omni-attr-key{width:120px;flex-shrink:0;font-size:11px;font-weight:600;color:var(--text-muted);font-family:Fira Code,monospace}.omni-attr-value{flex:1;font-size:11px;color:#e2e8f0;font-family:Fira Code,monospace;word-break:break-all}.omni-tree-content::-webkit-scrollbar,.omni-details-content::-webkit-scrollbar,.omni-attributes-table::-webkit-scrollbar{width:6px}.omni-tree-content::-webkit-scrollbar-track,.omni-details-content::-webkit-scrollbar-track,.omni-attributes-table::-webkit-scrollbar-track{background:transparent}.omni-tree-content::-webkit-scrollbar-thumb,.omni-details-content::-webkit-scrollbar-thumb,.omni-attributes-table::-webkit-scrollbar-thumb{background:var(--border);border-radius:8px}.omni-tree-content::-webkit-scrollbar-thumb:hover,.omni-details-content::-webkit-scrollbar-thumb:hover,.omni-attributes-table::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}.omni-quick-actions{display:flex;flex-direction:column;gap:16px}.omni-input-group{display:flex;flex-direction:column;gap:8px}.omni-input-field{width:100%;background:rgb(var(--rgb-well) / calc(.3 * var(--well-k)));border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 12px;color:var(--text);font-size:12px;outline:none;transition:all .2s ease}.omni-input-field:focus{border-color:var(--color-accent);background:rgb(var(--rgb-well) / calc(.5 * var(--well-k)))}.omni-gestures-container{display:flex;flex-direction:column;align-items:center;gap:12px;padding:16px;background:rgb(var(--rgb-well) / calc(.2 * var(--well-k)));border-radius:var(--radius-md);border:1px solid var(--border)}.omni-dpad{display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);gap:8px;width:120px;height:120px}.omni-dpad-btn{display:flex;align-items:center;justify-content:center;background:rgb(var(--rgb-fg) / .03);border:1px solid rgb(var(--rgb-fg) / .05);border-radius:8px;color:var(--text-muted);cursor:pointer;transition:all .2s ease}.omni-dpad-btn:hover{background:var(--color-accent);color:var(--color-on-accent);transform:scale(1.1)}.omni-clipboard-box{display:flex;gap:8px;align-items:center}.omni-clipboard-val{flex:1;background:#161b22b3;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border:1px solid var(--border);border-radius:4px;padding:8px;font-family:Fira Code,monospace;font-size:11px;color:var(--sky-400);min-height:32px;overflow-x:auto;white-space:nowrap}.omni-details-tabs{display:flex;background:rgb(var(--rgb-well) / calc(.5 * var(--well-k)));border-bottom:1px solid var(--border);flex-shrink:0}.omni-details-tab{display:flex;align-items:center;gap:5px;flex:1;padding:10px 8px;border:none;background:transparent;color:var(--text-muted);font-size:11px;font-weight:700;cursor:pointer;border-bottom:2px solid transparent;transition:all .15s ease;justify-content:center;min-width:0;white-space:nowrap}.omni-details-tab>svg{flex-shrink:0}.omni-details-tab>span{min-width:0;overflow:hidden;text-overflow:ellipsis}.omni-details-tab:hover:not(:disabled){color:var(--text);background:rgb(var(--rgb-fg) / .03)}.omni-details-tab.active{color:var(--color-accent);border-bottom-color:var(--color-accent);background:rgb(var(--rgb-accent) / .04)}.omni-details-tab:disabled{opacity:.3;cursor:not-allowed}.omni-locator-row{display:flex;align-items:flex-start;gap:10px;padding:10px 14px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border-radius:6px;border:1px solid var(--border);border-left:3px solid var(--color-accent);transition:all .15s;cursor:pointer}.omni-locator-row:hover{background:rgb(var(--rgb-fg) / .02);border-color:var(--color-accent)}.omni-locator-row.selected-for-code{border-color:var(--color-accent);background:rgb(var(--rgb-accent) / .06);box-shadow:none}.omni-locator-left{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.omni-locator-top{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.omni-stability-badge{display:inline-flex;align-items:center;gap:3px;font-size:11px;font-weight:800;padding:2px 6px;border-radius:4px}.omni-stability-badge.stable{background:rgb(var(--rgb-accent) / .12);color:var(--color-accent);border:1px solid rgb(var(--rgb-accent) / .25)}.omni-stability-badge.moderate{background:rgb(var(--rgb-amber-400) / .1);color:var(--amber-400);border:1px solid rgb(var(--rgb-amber-400) / .25)}.omni-stability-badge.fragile{background:#f43f5e1a;color:#f43f5e;border:1px solid rgba(244,63,94,.25)}.omni-stability-reason{font-size:10px;color:var(--text-muted);font-style:italic;line-height:1.3}.omni-section-badge{font-size:11px;font-weight:600;background:rgb(var(--rgb-accent) / .08);color:var(--color-accent);padding:2px 6px;border-radius:4px;margin-left:6px;vertical-align:middle}.omni-inspector-container.omni-embedded{height:100%}.omni-inspector-container.omni-embedded .omni-main-content{padding:0;gap:12px}.omni-summary-panel{display:flex;flex-direction:column;gap:18px}.omni-summary-hero{display:flex;align-items:flex-start;gap:12px;padding:14px;background:rgb(var(--rgb-accent) / .04);border:1px solid rgb(var(--rgb-accent) / .15);border-radius:8px;color:var(--color-accent)}.omni-summary-hero>svg{flex-shrink:0;margin-top:2px}.omni-summary-title{font-size:13px;font-weight:700;color:var(--text);margin-bottom:2px}.omni-summary-subtitle{font-size:11px;color:var(--text-muted);line-height:1.5}.omni-summary-stats{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}.omni-summary-stat{display:flex;flex-direction:column;gap:4px;padding:10px 12px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border:1px solid var(--border);border-radius:6px}.omni-summary-stat__label{font-size:11px;font-weight:700;color:var(--text-dim)}.omni-summary-stat__value{font-size:14px;font-weight:700;color:var(--color-accent);font-family:JetBrains Mono,monospace;word-break:break-all}.omni-summary-roles{display:flex;flex-direction:column;gap:4px}.omni-summary-role{display:flex;align-items:center;gap:10px;padding:8px 10px;background:rgb(var(--rgb-well) / calc(.25 * var(--well-k)));border:1px solid var(--border);border-radius:6px}.omni-summary-role__name{flex:1;font-size:12px;color:var(--text)}.omni-summary-role__count{font-size:11px;font-weight:700;color:var(--color-accent);background:rgb(var(--rgb-accent) / .06);padding:2px 8px;border-radius:4px;font-family:JetBrains Mono,monospace}.omni-search-hint{display:flex;align-items:center;gap:5px;padding:4px 14px;font-size:10px;color:var(--text-muted);border-bottom:1px solid var(--border)}.omni-codegen-panel{display:flex;flex-direction:column;gap:12px}.omni-codegen-frameworks{display:flex;gap:4px;flex-wrap:wrap}.omni-fw-btn{flex:1;padding:6px 4px;background:rgb(var(--rgb-fg) / .03);border:1px solid var(--border);border-radius:6px;color:var(--text-muted);font-size:10px;font-weight:700;cursor:pointer;transition:all .15s;white-space:nowrap}.omni-fw-btn:hover{background:rgb(var(--rgb-fg) / .06);color:var(--text)}.omni-fw-btn.active{background:rgb(var(--rgb-accent) / .08);border-color:rgb(var(--rgb-accent) / .4);color:var(--color-accent)}.omni-codegen-locator-selector{display:flex;align-items:center;gap:8px}.omni-codegen-label{font-size:11px;font-weight:700;color:var(--text-muted);white-space:nowrap}.omni-codegen-output{display:flex;flex-direction:column;border-radius:8px;border:1px solid var(--border);overflow:hidden}.omni-codegen-header{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;background:rgb(var(--rgb-well) / calc(.5 * var(--well-k)));border-bottom:1px solid var(--border)}.omni-codegen-lang{font-size:11px;font-weight:700;color:var(--color-accent)}.omni-codegen-pre{margin:0;padding:14px;background:#161b22b3;color:#e2e8f0;font-family:Fira Code,JetBrains Mono,monospace;font-size:11px;line-height:1.6;overflow-x:auto;white-space:pre-wrap;overflow-wrap:anywhere}.omni-codegen-pre code{font-family:inherit;font-size:inherit;color:inherit}.omni-verify-line{display:flex;align-items:center;gap:4px;margin-top:3px;font-size:10px;line-height:1.4}.omni-verify-line.is-ok{color:var(--color-success)}.omni-verify-line.is-warn{color:var(--amber-400)}.omni-verify-line.is-error{color:var(--red-400)}.omni-locators-empty{padding:10px 12px;font-size:11px;line-height:1.6;color:var(--text);opacity:.6}.omni-tree-error{display:flex;align-items:center;gap:6px;margin:8px;padding:8px 10px;border:1px solid rgb(var(--rgb-red-400) / .35);border-radius:8px;background:rgb(var(--rgb-red-400) / .08);color:var(--red-400);font-size:11px;line-height:1.5}.omni-tree-error>span{flex:1;min-width:0}.omni-tree-error-retry{flex-shrink:0;padding:3px 8px;border:1px solid rgb(var(--rgb-red-400) / .4);border-radius:6px;background:transparent;color:inherit;font-size:11px;font-weight:700;cursor:pointer}.omni-tree-error-retry:hover{background:rgb(var(--rgb-red-400) / .15)}:root[data-theme=light] .omni-screenshot-container,:root[data-theme=light] .omni-attributes-table,:root[data-theme=light] .omni-clipboard-val{background:var(--surface-2)}:root[data-theme=light] .omni-attr-value{color:var(--text)}:root[data-theme=light] .omni-stability-badge.fragile{background:rgb(var(--rgb-red) / .08);color:var(--red);border-color:rgb(var(--rgb-red) / .25)}:root[data-theme=light] .omni-codegen-pre{background:var(--surface)}.omni-summary-role__icon{display:inline-flex;color:var(--text-muted)}.omni-capture-meta{display:flex;align-items:center;gap:6px;padding:4px 12px;color:var(--text-muted);font-size:11px}.omni-capture-source{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;text-underline-offset:3px;cursor:help}.omni-capture-meta.is-stale{margin:6px 10px 0;padding:6px 8px 6px 10px;border:1px solid rgb(var(--rgb-amber) / .35);border-radius:var(--radius-sm);background:rgb(var(--rgb-amber) / .1);color:var(--text)}.omni-capture-meta.is-stale svg{flex:none;color:var(--color-warning)}.omni-capture-meta.is-stale span{flex:1;min-width:0}.omni-capture-refresh{flex:none;height:24px;padding:0 8px;border:1px solid var(--border-strong);border-radius:var(--radius-sm);background:var(--surface);color:var(--text);font-size:11px;font-weight:600;cursor:pointer}.omni-capture-refresh:hover{background:var(--surface-2)}.omni-capture-refresh:focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:1px}.omni-overlay.is-stale{opacity:.35}.omni-checks-panel{display:flex;flex-direction:column;gap:10px}.omni-checks-summary{display:flex;flex-wrap:wrap;gap:12px;margin:0;font-size:12px;font-weight:600}.omni-checks-summary span{display:inline-flex;align-items:center;gap:4px}.omni-checks-summary .is-pass{color:var(--color-success)}.omni-checks-summary .is-warn{color:var(--color-warning)}.omni-checks-summary .is-fail{color:var(--color-danger)}.omni-checks-list{display:flex;flex-direction:column;gap:6px;margin:0;padding:0;list-style:none}.omni-check{display:flex;align-items:flex-start;gap:8px;padding:8px 10px;border:1px solid var(--border);border-radius:6px;background:rgb(var(--rgb-well) / calc(.25 * var(--well-k)))}.omni-check-icon{display:inline-flex;flex:none;margin-top:1px;color:var(--text-muted)}.omni-check.is-pass .omni-check-icon{color:var(--color-success)}.omni-check.is-warn .omni-check-icon{color:var(--color-warning)}.omni-check.is-fail .omni-check-icon{color:var(--color-danger)}.omni-check.is-fail{border-color:var(--status-error-border)}.omni-check-body{min-width:0}.omni-check-label{color:var(--text);font-size:12px;font-weight:600}.omni-check-detail{margin-top:2px;color:var(--text-muted);font-size:11px;line-height:1.45;overflow-wrap:anywhere}.omni-tree{display:flex;flex-direction:column;min-width:0}.omni-tree-row{display:flex;align-items:center;gap:4px;height:26px;min-width:0;padding:0 8px 0 6px;border-radius:4px;font-size:12px;color:var(--text-dim);white-space:nowrap;overflow:hidden;cursor:pointer;flex-shrink:0}.omni-tree-row:hover,.omni-tree-row.is-hovered{background:rgb(var(--rgb-fg) / .05)}.omni-tree-row.is-selected{background:rgb(var(--rgb-accent) / .12);box-shadow:inset 2px 0 0 var(--color-accent)}.omni-tree-row:focus{outline:none}.omni-tree-row:focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:-2px}.omni-tree-row__lead{display:flex;align-items:center;align-self:stretch;flex-shrink:0}.omni-tree-row__indent{flex-shrink:0;align-self:stretch;background-image:linear-gradient(to right,var(--border) 1px,transparent 1px);background-size:10px 100%;background-position:5px 0;background-repeat:repeat-x}.omni-tree-row__caret,.omni-tree-row__icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--text-muted)}.omni-tree-row__caret{width:12px}.omni-tree-row__icon{margin-left:4px}.omni-tree-row__caret.is-locked{cursor:default;opacity:.4}.omni-tree-row__label{display:flex;flex:1 1 auto;align-items:center;min-width:0;overflow:hidden}.omni-tree-row__head{display:block;flex:0 1 auto;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.omni-tree-row__tail{display:flex;flex:0 0 auto;align-items:center;min-width:0;max-width:100%}.omni-tree-row__name{display:flex;flex:0 1 auto;align-items:center;min-width:0}.omni-tree-row__part,.omni-tree-row__type{min-width:0;overflow:hidden;text-overflow:ellipsis}.omni-tree-row__part{font-family:JetBrains Mono,Fira Code,monospace;flex:0 1 auto}.omni-tree-row__part.is-target{flex:0 0 auto;max-width:100%;color:var(--text)}.omni-tree-row__part.is-match{color:var(--color-highlight)}.omni-tree-row__part.is-current{text-decoration:underline;text-underline-offset:3px}.omni-tree-row__sep{flex:0 0 auto;padding:0 4px;color:var(--text-dim)}.omni-tree-row__type{flex:0 1 auto;margin-left:4px;font-size:11px;color:var(--text-dim)}.omni-tree-row__count{flex-shrink:0;margin-left:auto;padding-left:6px;font-family:JetBrains Mono,monospace;font-size:10px;color:var(--text-dim)}:root[data-theme=light] .omni-tree-row__part.is-match{color:var(--color-info)}:root[data-theme=light] .omni-tree-row.is-selected,:root[data-theme=light] .omni-tree-row.is-selected .omni-tree-row__sep,:root[data-theme=light] .omni-tree-row.is-selected .omni-tree-row__type,:root[data-theme=light] .omni-tree-row.is-selected .omni-tree-row__count{color:var(--text-muted)}.logcat-root{display:flex;flex-direction:column;flex:1;min-height:0}.log-toolbar{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;row-gap:6px;background:color-mix(in srgb,var(--surface-2) 60%,transparent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);padding:8px 16px;border-radius:var(--radius-md) var(--radius-md) 0 0;border:1px solid var(--border);border-bottom:none}.log-filter-group,.log-actions-group{display:flex;gap:8px;align-items:center;min-width:0;flex-wrap:wrap}.log-stat-pill{font-size:11px;background:rgb(var(--rgb-accent) / .1);color:var(--color-accent);padding:3px 8px;border-radius:4px;font-weight:700;display:flex;align-items:center;gap:6px}.log-live-dot{width:8px;height:8px;border-radius:50%;background:var(--text-muted);flex-shrink:0;transition:background .3s ease}.log-live-dot.active{background:var(--color-success);box-shadow:none;animation:logcat-live-pulse 2s infinite}@keyframes logcat-live-pulse{0%,to{opacity:1;box-shadow:none}50%{opacity:.6;box-shadow:none}}.log-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;min-height:200px}.log-empty-title{font-family:Outfit,sans-serif;font-size:14px;font-weight:700;color:var(--text);margin:0 0 6px;letter-spacing:.02em}.log-empty-subtitle{font-size:12px;color:var(--text-muted);max-width:300px;margin:0;line-height:1.5}.logcat-query{flex:1;min-width:160px}.logcat-count{opacity:.6}.logcat-rows{flex:1;overflow-y:auto;font-family:JetBrains Mono,monospace;font-size:11.5px;line-height:1.6;padding:8px 12px}.logcat-row{display:grid;grid-template-columns:56px 70px minmax(0,150px) minmax(0,160px) 12px;gap:4px 8px;align-items:baseline;padding:1px 0}.logcat-row:hover{background:rgb(var(--rgb-fg) / .03)}.logcat-time,.logcat-pid,.logcat-pkg,.logcat-tag{color:var(--text-muted);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.logcat-tag{color:#7dd3fc}.logcat-msg{grid-column:1 / -1;padding-left:8px;color:var(--text);min-width:0;white-space:pre-wrap;overflow-wrap:anywhere}.logcat-level{font-weight:700;text-align:center;border-radius:3px}.lvl-V,.lvl-D{color:var(--text-muted)}.lvl-I{color:var(--color-accent)}.lvl-W{color:var(--amber-400)}.lvl-E,.lvl-F{color:var(--red-400)}.logcat-row.is-hit{background:color-mix(in srgb,var(--color-accent) 12%,transparent)}.logcat-row.is-active-hit{background:color-mix(in srgb,var(--color-accent) 22%,transparent);box-shadow:inset 2px 0 0 var(--color-accent)}.logcat-rows.no-wrap{overflow-x:auto}.logcat-rows.no-wrap .logcat-row{grid-template-columns:56px 70px minmax(0,150px) minmax(0,160px) 12px minmax(0,1fr);width:max-content;min-width:100%}.logcat-rows.no-wrap .logcat-msg{grid-column:auto;padding-left:0;white-space:pre;overflow:hidden;text-overflow:ellipsis}.logcat-input-wrap{position:relative;display:flex;align-items:center}.logcat-find{width:120px}.logcat-query{padding-right:22px}.logcat-input-btn{position:absolute;right:4px;display:flex;align-items:center;justify-content:center;padding:2px;border:0;border-radius:3px;background:transparent;color:var(--text-muted);cursor:pointer}.logcat-input-btn:hover{color:var(--text);background:rgb(var(--rgb-fg) / .08)}.logcat-hit-count{position:absolute;right:8px;font-size:10px;font-variant-numeric:tabular-nums;color:var(--text-muted);pointer-events:none}.dc-btn-secondary.is-recording{color:var(--red-400);border-color:color-mix(in srgb,var(--red-400) 45%,transparent);background:color-mix(in srgb,var(--red-400) 12%,transparent)}.dc-btn-secondary.is-recording svg{fill:currentColor}.logcat-icon-btn{padding:4px 6px}.logcat-icon-btn:disabled{opacity:.4;cursor:default}.logcat-row.is-synthetic .logcat-msg{color:var(--amber-400);font-style:italic}.log-live-dot.is-error{background:var(--red-400);box-shadow:none}.logcat-status-banner{display:flex;align-items:center;gap:8px;padding:8px 10px;margin-bottom:8px;border-radius:var(--radius-sm);font-family:Outfit,sans-serif;font-size:12px;line-height:1.4}.logcat-status-banner.is-denied{background:rgb(var(--rgb-red-400) / .1);border:1px solid rgb(var(--rgb-red-400) / .3);color:#fecdd3}.logcat-status-banner.is-exhausted{background:rgb(var(--rgb-amber-400) / .1);border:1px solid rgb(var(--rgb-amber-400) / .3);color:#fde68a}:root[data-theme=light] .logcat-rows{background:var(--bg);border-radius:0 0 var(--radius-md) var(--radius-md)}.actions-panel{display:flex;flex-direction:column;gap:12px}.actions-section{display:flex;flex-direction:column;gap:10px;padding:14px 16px;border:1px solid var(--border);border-radius:var(--radius-md);background:rgb(var(--rgb-well) / calc(.2 * var(--well-k)))}.actions-section-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.actions-section-title{display:flex;align-items:center;gap:8px;margin:0;color:var(--text);font-family:Inter,sans-serif;font-size:13px;font-weight:600}.actions-section-title svg{color:var(--color-accent)}.actions-section-tools{display:flex;align-items:center;gap:8px}.actions-section-tools [aria-disabled=true]{opacity:.5;cursor:not-allowed}.actions-apps-tools{display:flex;align-items:center;gap:6px}.actions-search{position:relative;flex:1;display:flex;align-items:center}.actions-search .type-input-field{padding-left:28px}.actions-search-icon{position:absolute;left:9px;color:var(--text-dim);pointer-events:none}.actions-apps-list{list-style:none;margin:0;padding:0;max-height:216px;overflow-y:auto;border:1px solid var(--border);border-radius:var(--radius-sm)}.actions-apps-list:empty{display:none}.actions-app-row{display:flex;align-items:center;gap:8px;min-height:36px;padding:0 4px 0 10px;border-bottom:1px solid var(--border)}.actions-app-row:last-child{border-bottom:none}.actions-app-row:hover{background:rgb(var(--rgb-fg) / .03)}.actions-app-id{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text);font-family:JetBrains Mono,ui-monospace,monospace;font-size:12px}.actions-app-note{color:var(--text-muted);font-size:11px}.actions-app-tools{display:flex;align-items:center;gap:2px}.actions-app-uninstall{color:var(--status-error-fg)}.actions-list-note{display:flex;align-items:center;gap:10px;margin:0;color:var(--text-muted);font-size:12px}.actions-library-menu{min-width:240px;max-height:320px;overflow-y:auto}.actions-field-row{display:flex;align-items:center;gap:8px}.actions-field-label{flex:0 0 76px;color:var(--text-muted);font-size:12px;font-weight:500}.actions-field-row .type-input-field{flex:1;min-width:0}.actions-field-row .type-input-field,.actions-search .type-input-field{height:32px;padding-top:0;padding-bottom:0}.actions-field-hint{margin:0 0 0 84px;color:var(--text-muted);font-size:11px}.actions-status{min-height:16px;margin:0;color:var(--text-muted);font-size:11px}.actions-swipe{flex-direction:row;align-items:center;justify-content:space-between}.actions-swipe-buttons{display:flex;gap:6px}.actions-confirm-text{margin:0;line-height:1.6}.actions-confirm-text code{font-family:JetBrains Mono,ui-monospace,monospace;font-size:12px;word-break:break-all}.actions-confirm-device{white-space:nowrap}