@glassly/engine 0.1.0-dev.99 → 0.2.8-dev.445

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 (501) hide show
  1. package/README.md +28 -0
  2. package/build/engine.d.ts +32 -10
  3. package/build/engine.d.ts.map +1 -1
  4. package/build/engine.js +24 -16
  5. package/build/engine.js.map +1 -1
  6. package/build/facades/dev.d.ts +9 -0
  7. package/build/facades/dev.d.ts.map +1 -1
  8. package/build/facades/dev.js +9 -0
  9. package/build/facades/dev.js.map +1 -1
  10. package/build/facades/display.d.ts +10 -3
  11. package/build/facades/display.d.ts.map +1 -1
  12. package/build/facades/display.js +22 -8
  13. package/build/facades/display.js.map +1 -1
  14. package/build/facades/displayMirror.d.ts +11 -0
  15. package/build/facades/displayMirror.d.ts.map +1 -1
  16. package/build/facades/displayMirror.js +22 -0
  17. package/build/facades/displayMirror.js.map +1 -1
  18. package/build/facades/glasses.d.ts +31 -1
  19. package/build/facades/glasses.d.ts.map +1 -1
  20. package/build/facades/glasses.js +51 -0
  21. package/build/facades/glasses.js.map +1 -1
  22. package/build/facades/memory.d.ts +0 -6
  23. package/build/facades/memory.d.ts.map +1 -1
  24. package/build/facades/memory.js +1 -9
  25. package/build/facades/memory.js.map +1 -1
  26. package/build/facades/miniapps.d.ts +3 -1
  27. package/build/facades/miniapps.d.ts.map +1 -1
  28. package/build/facades/miniapps.js +3 -1
  29. package/build/facades/miniapps.js.map +1 -1
  30. package/build/facades/pairing.d.ts.map +1 -1
  31. package/build/facades/pairing.js +5 -4
  32. package/build/facades/pairing.js.map +1 -1
  33. package/build/facades/permissions.d.ts +2 -0
  34. package/build/facades/permissions.d.ts.map +1 -1
  35. package/build/facades/permissions.js +48 -0
  36. package/build/facades/permissions.js.map +1 -1
  37. package/build/facades/phoneNotifications.d.ts +20 -9
  38. package/build/facades/phoneNotifications.d.ts.map +1 -1
  39. package/build/facades/phoneNotifications.js +33 -26
  40. package/build/facades/phoneNotifications.js.map +1 -1
  41. package/build/facades/settings.d.ts.map +1 -1
  42. package/build/facades/settings.js +1 -2
  43. package/build/facades/settings.js.map +1 -1
  44. package/build/generated/releaseMetadata.js +4 -4
  45. package/build/generated/releaseMetadata.js.map +1 -1
  46. package/build/index.d.ts +6 -4
  47. package/build/index.d.ts.map +1 -1
  48. package/build/index.js +5 -4
  49. package/build/index.js.map +1 -1
  50. package/build/react/MentraLiveOtaFlow.js +2 -2
  51. package/build/react/MentraLiveOtaFlow.js.map +1 -1
  52. package/build/react/useMentraLiveOta.d.ts.map +1 -1
  53. package/build/react/useMentraLiveOta.js +8 -7
  54. package/build/react/useMentraLiveOta.js.map +1 -1
  55. package/build/runtime/config.d.ts +1 -1
  56. package/build/runtime/config.d.ts.map +1 -1
  57. package/build/runtime/config.js.map +1 -1
  58. package/build/services/AppRegistry.d.ts +4 -1
  59. package/build/services/AppRegistry.d.ts.map +1 -1
  60. package/build/services/AppRegistry.js +21 -1
  61. package/build/services/AppRegistry.js.map +1 -1
  62. package/build/services/BlobStore.d.ts +2 -2
  63. package/build/services/BlobStore.js +3 -3
  64. package/build/services/BlobStore.js.map +1 -1
  65. package/build/services/CloudClientService.d.ts +7 -3
  66. package/build/services/CloudClientService.d.ts.map +1 -1
  67. package/build/services/CloudClientService.js +34 -9
  68. package/build/services/CloudClientService.js.map +1 -1
  69. package/build/services/DevServerBridge.d.ts +1 -18
  70. package/build/services/DevServerBridge.d.ts.map +1 -1
  71. package/build/services/DevServerBridge.js +9 -8
  72. package/build/services/DevServerBridge.js.map +1 -1
  73. package/build/services/DeviceEventRouter.d.ts.map +1 -1
  74. package/build/services/DeviceEventRouter.js +58 -71
  75. package/build/services/DeviceEventRouter.js.map +1 -1
  76. package/build/services/DisplayDiagnostics.d.ts +5 -0
  77. package/build/services/DisplayDiagnostics.d.ts.map +1 -0
  78. package/build/services/DisplayDiagnostics.js +105 -0
  79. package/build/services/DisplayDiagnostics.js.map +1 -0
  80. package/build/services/DisplayProcessor.d.ts +6 -7
  81. package/build/services/DisplayProcessor.d.ts.map +1 -1
  82. package/build/services/DisplayProcessor.js +17 -45
  83. package/build/services/DisplayProcessor.js.map +1 -1
  84. package/build/services/GestureDotsService.d.ts +10 -4
  85. package/build/services/GestureDotsService.d.ts.map +1 -1
  86. package/build/services/GestureDotsService.js +70 -16
  87. package/build/services/GestureDotsService.js.map +1 -1
  88. package/build/services/GlassesKeyboardInput.d.ts +77 -0
  89. package/build/services/GlassesKeyboardInput.d.ts.map +1 -0
  90. package/build/services/GlassesKeyboardInput.js +261 -0
  91. package/build/services/GlassesKeyboardInput.js.map +1 -0
  92. package/build/services/GlassesSensorService.d.ts +47 -0
  93. package/build/services/GlassesSensorService.d.ts.map +1 -0
  94. package/build/services/GlassesSensorService.js +242 -0
  95. package/build/services/GlassesSensorService.js.map +1 -0
  96. package/build/services/GlassesTouchInput.d.ts +14 -0
  97. package/build/services/GlassesTouchInput.d.ts.map +1 -0
  98. package/build/services/GlassesTouchInput.js +107 -0
  99. package/build/services/GlassesTouchInput.js.map +1 -0
  100. package/build/services/HeadingService.d.ts +0 -6
  101. package/build/services/HeadingService.d.ts.map +1 -1
  102. package/build/services/HeadingService.js +0 -27
  103. package/build/services/HeadingService.js.map +1 -1
  104. package/build/services/HotspotShutdown.d.ts.map +1 -1
  105. package/build/services/HotspotShutdown.js +2 -1
  106. package/build/services/HotspotShutdown.js.map +1 -1
  107. package/build/services/JSCrashloopReportService.js +2 -2
  108. package/build/services/JSCrashloopReportService.js.map +1 -1
  109. package/build/services/JSRouter.d.ts +6 -4
  110. package/build/services/JSRouter.d.ts.map +1 -1
  111. package/build/services/JSRouter.js +15 -13
  112. package/build/services/JSRouter.js.map +1 -1
  113. package/build/services/LocalDisplayManager.d.ts +35 -7
  114. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  115. package/build/services/LocalDisplayManager.js +105 -27
  116. package/build/services/LocalDisplayManager.js.map +1 -1
  117. package/build/services/LocalMiniappDataMigration.d.ts +1 -1
  118. package/build/services/LocalMiniappDataMigration.js +1 -1
  119. package/build/services/LocalMiniappDataMigration.js.map +1 -1
  120. package/build/services/LocalMiniappRuntime.d.ts +64 -11
  121. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  122. package/build/services/LocalMiniappRuntime.js +441 -35
  123. package/build/services/LocalMiniappRuntime.js.map +1 -1
  124. package/build/services/LocalSttFallbackCoordinator.d.ts +3 -0
  125. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  126. package/build/services/LocalSttFallbackCoordinator.js +27 -8
  127. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  128. package/build/services/MemoryStore.d.ts +8 -33
  129. package/build/services/MemoryStore.d.ts.map +1 -1
  130. package/build/services/MemoryStore.js +30 -56
  131. package/build/services/MemoryStore.js.map +1 -1
  132. package/build/services/MiniappEngine.d.ts +3 -3
  133. package/build/services/MiniappEngine.js +7 -7
  134. package/build/services/MiniappEngine.js.map +1 -1
  135. package/build/services/MiniappLauncher.d.ts +8 -0
  136. package/build/services/MiniappLauncher.d.ts.map +1 -1
  137. package/build/services/MiniappLauncher.js +19 -1
  138. package/build/services/MiniappLauncher.js.map +1 -1
  139. package/build/services/MirrorService.d.ts +24 -0
  140. package/build/services/MirrorService.d.ts.map +1 -0
  141. package/build/services/MirrorService.js +132 -0
  142. package/build/services/MirrorService.js.map +1 -0
  143. package/build/services/NativeNavigationService.d.ts +2 -3
  144. package/build/services/NativeNavigationService.d.ts.map +1 -1
  145. package/build/services/NativeNavigationService.js +24 -21
  146. package/build/services/NativeNavigationService.js.map +1 -1
  147. package/build/services/NavigationHandlers.d.ts.map +1 -1
  148. package/build/services/NavigationHandlers.js +10 -5
  149. package/build/services/NavigationHandlers.js.map +1 -1
  150. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  151. package/build/services/OtaInstallCoordinator.js +24 -23
  152. package/build/services/OtaInstallCoordinator.js.map +1 -1
  153. package/build/services/PairedGlassesLatch.d.ts +7 -0
  154. package/build/services/PairedGlassesLatch.d.ts.map +1 -0
  155. package/build/services/PairedGlassesLatch.js +38 -0
  156. package/build/services/PairedGlassesLatch.js.map +1 -0
  157. package/build/services/PhoneActivity.d.ts +23 -0
  158. package/build/services/PhoneActivity.d.ts.map +1 -0
  159. package/build/services/PhoneActivity.js +111 -0
  160. package/build/services/PhoneActivity.js.map +1 -0
  161. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -1
  162. package/build/services/PhoneCameraFovCoordinator.js +4 -3
  163. package/build/services/PhoneCameraFovCoordinator.js.map +1 -1
  164. package/build/services/PhoneNotificationsSync.d.ts +40 -6
  165. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  166. package/build/services/PhoneNotificationsSync.js +160 -84
  167. package/build/services/PhoneNotificationsSync.js.map +1 -1
  168. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  169. package/build/services/PhonePhotoCoordinator.js +6 -5
  170. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  171. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  172. package/build/services/PhoneStreamCoordinator.js +8 -7
  173. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  174. package/build/services/STTModelManager.d.ts +3 -0
  175. package/build/services/STTModelManager.d.ts.map +1 -1
  176. package/build/services/STTModelManager.js +15 -1
  177. package/build/services/STTModelManager.js.map +1 -1
  178. package/build/services/SceneRenderer.d.ts +43 -2
  179. package/build/services/SceneRenderer.d.ts.map +1 -1
  180. package/build/services/SceneRenderer.js +123 -8
  181. package/build/services/SceneRenderer.js.map +1 -1
  182. package/build/services/StreamLifecycleController.d.ts.map +1 -1
  183. package/build/services/StreamLifecycleController.js +6 -14
  184. package/build/services/StreamLifecycleController.js.map +1 -1
  185. package/build/services/TTSModelManager.js +1 -1
  186. package/build/services/TTSModelManager.js.map +1 -1
  187. package/build/services/UIRouter.d.ts +2 -2
  188. package/build/services/UIRouter.js +5 -5
  189. package/build/services/UIRouter.js.map +1 -1
  190. package/build/services/asg/galleryPathMigration.js +1 -1
  191. package/build/services/asg/galleryPathMigration.js.map +1 -1
  192. package/build/services/asg/gallerySyncService.js +2 -2
  193. package/build/services/asg/gallerySyncService.js.map +1 -1
  194. package/build/services/asg/localStorageService.d.ts.map +1 -1
  195. package/build/services/asg/localStorageService.js +3 -3
  196. package/build/services/asg/localStorageService.js.map +1 -1
  197. package/build/services/debug/DashboardOpenTrace.d.ts +32 -0
  198. package/build/services/debug/DashboardOpenTrace.d.ts.map +1 -0
  199. package/build/services/debug/DashboardOpenTrace.js +128 -0
  200. package/build/services/debug/DashboardOpenTrace.js.map +1 -0
  201. package/build/services/debug/dashboardOpenTimeline.d.ts +77 -0
  202. package/build/services/debug/dashboardOpenTimeline.d.ts.map +1 -0
  203. package/build/services/debug/dashboardOpenTimeline.js +195 -0
  204. package/build/services/debug/dashboardOpenTimeline.js.map +1 -0
  205. package/build/services/effectiveCapabilities.d.ts.map +1 -1
  206. package/build/services/effectiveCapabilities.js +25 -13
  207. package/build/services/effectiveCapabilities.js.map +1 -1
  208. package/build/services/gestureClaims.d.ts +34 -15
  209. package/build/services/gestureClaims.d.ts.map +1 -1
  210. package/build/services/gestureClaims.js +42 -21
  211. package/build/services/gestureClaims.js.map +1 -1
  212. package/build/services/manifestFields.d.ts +9 -0
  213. package/build/services/manifestFields.d.ts.map +1 -0
  214. package/build/services/manifestFields.js +26 -0
  215. package/build/services/manifestFields.js.map +1 -0
  216. package/build/services/memoryStoreInstance.d.ts +0 -10
  217. package/build/services/memoryStoreInstance.d.ts.map +1 -1
  218. package/build/services/memoryStoreInstance.js +2 -31
  219. package/build/services/memoryStoreInstance.js.map +1 -1
  220. package/build/services/mirrorSnapshot.d.ts +16 -0
  221. package/build/services/mirrorSnapshot.d.ts.map +1 -0
  222. package/build/services/mirrorSnapshot.js +102 -0
  223. package/build/services/mirrorSnapshot.js.map +1 -0
  224. package/build/services/nativeNavigationGate.d.ts +8 -0
  225. package/build/services/nativeNavigationGate.d.ts.map +1 -0
  226. package/build/services/nativeNavigationGate.js +12 -0
  227. package/build/services/nativeNavigationGate.js.map +1 -0
  228. package/build/services/notificationAppCatalog.d.ts +7 -0
  229. package/build/services/notificationAppCatalog.d.ts.map +1 -0
  230. package/build/services/notificationAppCatalog.js +16 -0
  231. package/build/services/notificationAppCatalog.js.map +1 -0
  232. package/build/services/notifications/notificationPolicy.d.ts +55 -0
  233. package/build/services/notifications/notificationPolicy.d.ts.map +1 -0
  234. package/build/services/notifications/notificationPolicy.js +41 -0
  235. package/build/services/notifications/notificationPolicy.js.map +1 -0
  236. package/build/services/pages/OverlayPages.d.ts +26 -0
  237. package/build/services/pages/OverlayPages.d.ts.map +1 -0
  238. package/build/services/pages/OverlayPages.js +80 -0
  239. package/build/services/pages/OverlayPages.js.map +1 -0
  240. package/build/services/pages/PageHost.d.ts +32 -0
  241. package/build/services/pages/PageHost.d.ts.map +1 -0
  242. package/build/services/pages/PageHost.js +99 -0
  243. package/build/services/pages/PageHost.js.map +1 -0
  244. package/build/services/pages/overlayApps.d.ts +25 -0
  245. package/build/services/pages/overlayApps.d.ts.map +1 -0
  246. package/build/services/pages/overlayApps.js +66 -0
  247. package/build/services/pages/overlayApps.js.map +1 -0
  248. package/build/services/pages/pageEligibility.d.ts +9 -0
  249. package/build/services/pages/pageEligibility.d.ts.map +1 -0
  250. package/build/services/pages/pageEligibility.js +27 -0
  251. package/build/services/pages/pageEligibility.js.map +1 -0
  252. package/build/services/settingsBridge.d.ts +58 -0
  253. package/build/services/settingsBridge.d.ts.map +1 -0
  254. package/build/services/settingsBridge.js +90 -0
  255. package/build/services/settingsBridge.js.map +1 -0
  256. package/build/services/speakerProfileStoreInstance.js +1 -1
  257. package/build/services/speakerProfileStoreInstance.js.map +1 -1
  258. package/build/services/uiShim.d.ts +1 -1
  259. package/build/services/uiShim.js +4 -4
  260. package/build/services/uiShim.js.map +1 -1
  261. package/build/stores/appVisibility.d.ts +28 -0
  262. package/build/stores/appVisibility.d.ts.map +1 -1
  263. package/build/stores/appVisibility.js +34 -0
  264. package/build/stores/appVisibility.js.map +1 -1
  265. package/build/stores/apps.d.ts +13 -0
  266. package/build/stores/apps.d.ts.map +1 -1
  267. package/build/stores/apps.js +66 -12
  268. package/build/stores/apps.js.map +1 -1
  269. package/build/stores/bluetoothSettingKeys.js +1 -1
  270. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  271. package/build/stores/display.d.ts +3 -3
  272. package/build/stores/display.d.ts.map +1 -1
  273. package/build/stores/display.js +16 -4
  274. package/build/stores/display.js.map +1 -1
  275. package/build/stores/glasses.d.ts.map +1 -1
  276. package/build/stores/glasses.js +14 -1
  277. package/build/stores/glasses.js.map +1 -1
  278. package/build/stores/settings.d.ts +1 -0
  279. package/build/stores/settings.d.ts.map +1 -1
  280. package/build/stores/settings.js +170 -44
  281. package/build/stores/settings.js.map +1 -1
  282. package/build/types/applet.d.ts +14 -1
  283. package/build/types/applet.d.ts.map +1 -1
  284. package/build/types/applet.js.map +1 -1
  285. package/build/types/capabilities/even-realities-g2.d.ts.map +1 -1
  286. package/build/types/capabilities/even-realities-g2.js +5 -0
  287. package/build/types/capabilities/even-realities-g2.js.map +1 -1
  288. package/build/types/capabilities/simulated-glasses.d.ts +1 -1
  289. package/build/types/capabilities/simulated-glasses.d.ts.map +1 -1
  290. package/build/types/capabilities/simulated-glasses.js +7 -4
  291. package/build/types/capabilities/simulated-glasses.js.map +1 -1
  292. package/build/types/hardware.d.ts +20 -1
  293. package/build/types/hardware.d.ts.map +1 -1
  294. package/build/types/hardware.js +2 -0
  295. package/build/types/hardware.js.map +1 -1
  296. package/build/types/index.d.ts +1 -0
  297. package/build/types/index.d.ts.map +1 -1
  298. package/build/types/index.js +1 -0
  299. package/build/types/index.js.map +1 -1
  300. package/build/utils/debouncedPatch.d.ts +3 -1
  301. package/build/utils/debouncedPatch.d.ts.map +1 -1
  302. package/build/utils/debouncedPatch.js +6 -3
  303. package/build/utils/debouncedPatch.js.map +1 -1
  304. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  305. package/build/utils/devMiniappLaunch.js +4 -3
  306. package/build/utils/devMiniappLaunch.js.map +1 -1
  307. package/build/utils/display/measurer/TextMeasurer.d.ts +2 -159
  308. package/build/utils/display/measurer/TextMeasurer.d.ts.map +1 -1
  309. package/build/utils/display/measurer/TextMeasurer.js +2 -272
  310. package/build/utils/display/measurer/TextMeasurer.js.map +1 -1
  311. package/build/utils/display/measurer/script-detection.d.ts +1 -52
  312. package/build/utils/display/measurer/script-detection.d.ts.map +1 -1
  313. package/build/utils/display/measurer/script-detection.js +2 -183
  314. package/build/utils/display/measurer/script-detection.js.map +1 -1
  315. package/build/utils/display/pixelArt.d.ts +3 -0
  316. package/build/utils/display/pixelArt.d.ts.map +1 -0
  317. package/build/utils/display/pixelArt.js +3 -0
  318. package/build/utils/display/pixelArt.js.map +1 -0
  319. package/build/utils/display/profiles/g1.d.ts +1 -32
  320. package/build/utils/display/profiles/g1.d.ts.map +1 -1
  321. package/build/utils/display/profiles/g1.js +2 -212
  322. package/build/utils/display/profiles/g1.js.map +1 -1
  323. package/build/utils/display/profiles/g2.d.ts +1 -12
  324. package/build/utils/display/profiles/g2.d.ts.map +1 -1
  325. package/build/utils/display/profiles/g2.js +2 -33
  326. package/build/utils/display/profiles/g2.js.map +1 -1
  327. package/build/utils/display/profiles/nex.d.ts +1 -9
  328. package/build/utils/display/profiles/nex.d.ts.map +1 -1
  329. package/build/utils/display/profiles/nex.js +2 -149
  330. package/build/utils/display/profiles/nex.js.map +1 -1
  331. package/build/utils/display/profiles/types.d.ts +1 -102
  332. package/build/utils/display/profiles/types.d.ts.map +1 -1
  333. package/build/utils/display/profiles/types.js.map +1 -1
  334. package/build/utils/display/profiles/z100.d.ts +1 -32
  335. package/build/utils/display/profiles/z100.d.ts.map +1 -1
  336. package/build/utils/display/profiles/z100.js +2 -181
  337. package/build/utils/display/profiles/z100.js.map +1 -1
  338. package/build/utils/display/scene/degrade.d.ts.map +1 -1
  339. package/build/utils/display/scene/degrade.js +4 -1
  340. package/build/utils/display/scene/degrade.js.map +1 -1
  341. package/build/utils/display/scene/differ.d.ts +13 -1
  342. package/build/utils/display/scene/differ.d.ts.map +1 -1
  343. package/build/utils/display/scene/differ.js +22 -0
  344. package/build/utils/display/scene/differ.js.map +1 -1
  345. package/build/utils/display/scene/index.d.ts +1 -1
  346. package/build/utils/display/scene/index.d.ts.map +1 -1
  347. package/build/utils/display/scene/index.js.map +1 -1
  348. package/build/utils/display/scene/process.d.ts.map +1 -1
  349. package/build/utils/display/scene/process.js +183 -11
  350. package/build/utils/display/scene/process.js.map +1 -1
  351. package/build/utils/display/scene/store.d.ts +1 -1
  352. package/build/utils/display/scene/store.d.ts.map +1 -1
  353. package/build/utils/display/scene/store.js +0 -0
  354. package/build/utils/display/scene/store.js.map +1 -1
  355. package/build/utils/display/scene/svgPath.d.ts +9 -0
  356. package/build/utils/display/scene/svgPath.d.ts.map +1 -0
  357. package/build/utils/display/scene/svgPath.js +167 -0
  358. package/build/utils/display/scene/svgPath.js.map +1 -0
  359. package/build/utils/display/scene/types.d.ts +2 -142
  360. package/build/utils/display/scene/types.d.ts.map +1 -1
  361. package/build/utils/display/scene/types.js +0 -0
  362. package/build/utils/display/scene/types.js.map +1 -1
  363. package/build/utils/display/wrapper/TextWrapper.d.ts +1 -101
  364. package/build/utils/display/wrapper/TextWrapper.d.ts.map +1 -1
  365. package/build/utils/display/wrapper/TextWrapper.js +2 -470
  366. package/build/utils/display/wrapper/TextWrapper.js.map +1 -1
  367. package/build/utils/display/wrapper/types.d.ts +2 -74
  368. package/build/utils/display/wrapper/types.d.ts.map +1 -1
  369. package/build/utils/display/wrapper/types.js +2 -10
  370. package/build/utils/display/wrapper/types.js.map +1 -1
  371. package/build/utils/hardware/hardware.js +1 -1
  372. package/build/utils/hardware/hardware.js.map +1 -1
  373. package/build/utils/timers/timers.d.ts.map +1 -1
  374. package/build/utils/timers/timers.js +26 -4
  375. package/build/utils/timers/timers.js.map +1 -1
  376. package/package.json +8 -8
  377. package/src/engine.ts +24 -15
  378. package/src/facades/dev.ts +10 -0
  379. package/src/facades/display.ts +21 -8
  380. package/src/facades/displayMirror.ts +29 -0
  381. package/src/facades/glasses.ts +61 -1
  382. package/src/facades/memory.ts +1 -12
  383. package/src/facades/miniapps.ts +4 -1
  384. package/src/facades/pairing.ts +8 -6
  385. package/src/facades/permissions.ts +46 -0
  386. package/src/facades/phoneNotifications.ts +45 -26
  387. package/src/facades/settings.ts +1 -2
  388. package/src/generated/releaseMetadata.ts +4 -4
  389. package/src/index.ts +6 -9
  390. package/src/react/MentraLiveOtaFlow.tsx +2 -2
  391. package/src/react/useMentraLiveOta.ts +14 -8
  392. package/src/runtime/config.ts +1 -1
  393. package/src/services/AppRegistry.ts +43 -7
  394. package/src/services/BlobStore.ts +3 -3
  395. package/src/services/CloudClientService.ts +37 -10
  396. package/src/services/DevServerBridge.ts +12 -10
  397. package/src/services/DeviceEventRouter.ts +73 -74
  398. package/src/services/DisplayDiagnostics.ts +107 -0
  399. package/src/services/DisplayProcessor.ts +20 -55
  400. package/src/services/GestureDotsService.ts +77 -16
  401. package/src/services/GlassesKeyboardInput.ts +306 -0
  402. package/src/services/GlassesSensorService.ts +233 -0
  403. package/src/services/GlassesTouchInput.ts +128 -0
  404. package/src/services/HeadingService.ts +0 -24
  405. package/src/services/HotspotShutdown.ts +3 -1
  406. package/src/services/JSCrashloopReportService.ts +2 -2
  407. package/src/services/JSRouter.ts +29 -14
  408. package/src/services/LocalDisplayManager.ts +112 -26
  409. package/src/services/LocalMiniappDataMigration.ts +1 -1
  410. package/src/services/LocalMiniappRuntime.ts +500 -43
  411. package/src/services/LocalSttFallbackCoordinator.ts +28 -7
  412. package/src/services/MemoryStore.ts +32 -80
  413. package/src/services/MiniappEngine.ts +7 -7
  414. package/src/services/MiniappLauncher.ts +25 -1
  415. package/src/services/MirrorService.ts +139 -0
  416. package/src/services/NativeNavigationService.ts +29 -25
  417. package/src/services/NavigationHandlers.ts +10 -5
  418. package/src/services/OtaInstallCoordinator.ts +36 -34
  419. package/src/services/PairedGlassesLatch.ts +39 -0
  420. package/src/services/PhoneActivity.ts +116 -0
  421. package/src/services/PhoneCameraFovCoordinator.ts +6 -4
  422. package/src/services/PhoneNotificationsSync.ts +185 -103
  423. package/src/services/PhonePhotoCoordinator.ts +9 -10
  424. package/src/services/PhoneStreamCoordinator.ts +13 -11
  425. package/src/services/STTModelManager.ts +15 -1
  426. package/src/services/SceneRenderer.ts +148 -10
  427. package/src/services/StreamLifecycleController.ts +9 -7
  428. package/src/services/TTSModelManager.ts +1 -1
  429. package/src/services/UIRouter.ts +5 -5
  430. package/src/services/asg/galleryPathMigration.ts +1 -1
  431. package/src/services/asg/gallerySyncService.ts +2 -2
  432. package/src/services/asg/localStorageService.ts +3 -3
  433. package/src/services/debug/DashboardOpenTrace.ts +153 -0
  434. package/src/services/debug/dashboardOpenTimeline.ts +237 -0
  435. package/src/services/effectiveCapabilities.ts +32 -13
  436. package/src/services/gestureClaims.ts +72 -23
  437. package/src/services/manifestFields.ts +23 -0
  438. package/src/services/memoryStoreInstance.ts +2 -34
  439. package/src/services/mirrorSnapshot.ts +116 -0
  440. package/src/services/nativeNavigationGate.ts +14 -0
  441. package/src/services/notificationAppCatalog.ts +21 -0
  442. package/src/services/notifications/notificationPolicy.ts +87 -0
  443. package/src/services/pages/OverlayPages.ts +86 -0
  444. package/src/services/pages/PageHost.ts +116 -0
  445. package/src/services/pages/overlayApps.ts +72 -0
  446. package/src/services/pages/pageEligibility.ts +30 -0
  447. package/src/services/settingsBridge.ts +111 -0
  448. package/src/services/speakerProfileStoreInstance.ts +1 -1
  449. package/src/services/uiShim.ts +4 -4
  450. package/src/stores/appVisibility.ts +45 -0
  451. package/src/stores/apps.ts +110 -32
  452. package/src/stores/bluetoothSettingKeys.ts +1 -1
  453. package/src/stores/display.ts +18 -7
  454. package/src/stores/glasses.ts +15 -1
  455. package/src/stores/settings.ts +175 -51
  456. package/src/types/applet.ts +14 -1
  457. package/src/types/capabilities/even-realities-g2.ts +6 -0
  458. package/src/types/capabilities/simulated-glasses.ts +8 -4
  459. package/src/types/hardware.ts +34 -1
  460. package/src/types/index.ts +1 -0
  461. package/src/utils/debouncedPatch.ts +8 -4
  462. package/src/utils/devMiniappLaunch.ts +5 -3
  463. package/src/utils/display/measurer/TextMeasurer.ts +3 -346
  464. package/src/utils/display/measurer/script-detection.ts +10 -218
  465. package/src/utils/display/pixelArt.ts +3 -0
  466. package/src/utils/display/profiles/g1.ts +2 -236
  467. package/src/utils/display/profiles/g2.ts +2 -39
  468. package/src/utils/display/profiles/nex.ts +2 -166
  469. package/src/utils/display/profiles/types.ts +9 -132
  470. package/src/utils/display/profiles/z100.ts +2 -198
  471. package/src/utils/display/scene/degrade.ts +4 -1
  472. package/src/utils/display/scene/differ.ts +25 -1
  473. package/src/utils/display/scene/index.ts +5 -0
  474. package/src/utils/display/scene/process.ts +196 -13
  475. package/src/utils/display/scene/store.ts +0 -0
  476. package/src/utils/display/scene/svgPath.ts +163 -0
  477. package/src/utils/display/scene/types.ts +0 -0
  478. package/src/utils/display/wrapper/TextWrapper.ts +2 -546
  479. package/src/utils/display/wrapper/types.ts +3 -102
  480. package/src/utils/hardware/hardware.ts +1 -1
  481. package/src/utils/timers/timers.ts +32 -4
  482. package/build/services/CustomDashboardModel.d.ts +0 -48
  483. package/build/services/CustomDashboardModel.d.ts.map +0 -1
  484. package/build/services/CustomDashboardModel.js +0 -73
  485. package/build/services/CustomDashboardModel.js.map +0 -1
  486. package/build/services/CustomDashboardService.d.ts +0 -63
  487. package/build/services/CustomDashboardService.d.ts.map +0 -1
  488. package/build/services/CustomDashboardService.js +0 -576
  489. package/build/services/CustomDashboardService.js.map +0 -1
  490. package/build/services/DashboardCoordinator.d.ts +0 -26
  491. package/build/services/DashboardCoordinator.d.ts.map +0 -1
  492. package/build/services/DashboardCoordinator.js +0 -125
  493. package/build/services/DashboardCoordinator.js.map +0 -1
  494. package/build/services/iosNotificationAppCatalog.d.ts +0 -13
  495. package/build/services/iosNotificationAppCatalog.d.ts.map +0 -1
  496. package/build/services/iosNotificationAppCatalog.js +0 -28
  497. package/build/services/iosNotificationAppCatalog.js.map +0 -1
  498. package/src/services/CustomDashboardModel.ts +0 -83
  499. package/src/services/CustomDashboardService.ts +0 -598
  500. package/src/services/DashboardCoordinator.ts +0 -121
  501. package/src/services/iosNotificationAppCatalog.ts +0 -39
@@ -22,8 +22,6 @@ class HeadingService {
22
22
  private nativeSub: {remove: () => void} | null = null
23
23
  private lastDegrees: number | null = null
24
24
  private nativeStarted = false
25
- /** While true, an external source (glasses magnetometer) owns the stream and phone-compass ticks are dropped. */
26
- private externalSourceActive = false
27
25
 
28
26
  private constructor() {}
29
27
 
@@ -34,27 +32,6 @@ class HeadingService {
34
32
  return HeadingService.instance
35
33
  }
36
34
 
37
- /** While active, phone compass updates are suppressed in favor of pushExternalHeading(). */
38
- public setExternalSourceActive(active: boolean): void {
39
- if (this.externalSourceActive === active) return
40
- this.externalSourceActive = active
41
- console.log(`${LOG_TAG}: external heading source ${active ? "active" : "inactive"}`)
42
- }
43
-
44
- /** Fan an external heading (degrees 0…359) out to listeners; no-op unless the external source is active. */
45
- public pushExternalHeading(degrees: number): void {
46
- if (!this.externalSourceActive) return
47
- if (!Number.isFinite(degrees)) return
48
- this.lastDegrees = degrees
49
- this.listeners.forEach((l) => {
50
- try {
51
- l(degrees)
52
- } catch (err) {
53
- console.error(`${LOG_TAG}: listener threw`, err)
54
- }
55
- })
56
- }
57
-
58
35
  public addListener(listener: HeadingListener): () => void {
59
36
  this.listeners.add(listener)
60
37
  if (!this.nativeStarted) {
@@ -79,7 +56,6 @@ class HeadingService {
79
56
  if (this.nativeStarted) return
80
57
  this.nativeStarted = true
81
58
  this.nativeSub = CrustModule.addListener("onHeading", (data) => {
82
- if (this.externalSourceActive) return
83
59
  const deg = Number(data.degrees)
84
60
  if (!Number.isFinite(deg)) return
85
61
  this.lastDegrees = deg
@@ -1,3 +1,5 @@
1
+ import {BgTimer} from "../utils/timers"
2
+
1
3
  type HotspotState = {state: "disabled" | "enabled"}
2
4
 
3
5
  type HotspotShutdownOptions = {
@@ -7,7 +9,7 @@ type HotspotShutdownOptions = {
7
9
  sleep?: (delayMs: number) => Promise<void>
8
10
  }
9
11
 
10
- const sleep = (delayMs: number) => new Promise<void>((resolve) => setTimeout(resolve, delayMs))
12
+ const sleep = (delayMs: number) => new Promise<void>((resolve) => BgTimer.setTimeout(resolve, delayMs))
11
13
 
12
14
  /**
13
15
  * Disable a glasses hotspot with a bounded retry. ASG APK replacement keeps the
@@ -25,7 +25,7 @@ export async function submitJSCrashloopReport(params: {
25
25
  trigger: {
26
26
  type: "automatic",
27
27
  source: "miniapp_crashloop",
28
- reason: "glasslyjs_crashloop_disabled",
28
+ reason: "js_crashloop_disabled",
29
29
  sourceAppletPackageName: packageName,
30
30
  sourceAppletName: appName,
31
31
  },
@@ -34,7 +34,7 @@ export async function submitJSCrashloopReport(params: {
34
34
  actualBehavior: JSON.stringify({reason, lastLogLines}, null, 2),
35
35
  systemPriority: "critical",
36
36
  },
37
- throttleKey: `glasslyjs_crashloop:${packageName}`,
37
+ throttleKey: `js_crashloop:${packageName}`,
38
38
  })
39
39
 
40
40
  const status = toAutomaticReportSubmissionStatus(result)
@@ -4,14 +4,14 @@
4
4
  * {@link LocalMiniappRuntime} handler set.
5
5
  *
6
6
  * Rather than re-implement the 33 dispatch arms inline, the router
7
- * consumes Crust's `glasslyjs_message` Expo event and forwards its
7
+ * consumes Crust's `js_message` Expo event and forwards its
8
8
  * `__bridge.send(raw)` payloads to {@link LocalMiniappRuntime.handleRawMessage}.
9
9
  * The SDK envelope shape (`{type: "DISPLAY", ...}` etc.) is unchanged from
10
10
  * the WebView path, so every existing handler runs verbatim. What changes
11
11
  * is the *transport*:
12
12
  *
13
13
  * - **Inbound** (background JS → host): `__dispatch("__bridge", "send",
14
- * [rawJsonString])` → `glasslyjs_message` event → router →
14
+ * [rawJsonString])` → `js_message` event → router →
15
15
  * `LocalMiniappRuntime.handleRawMessage(packageName, raw)`.
16
16
  * - **Outbound** (host → background JS): every package registered with
17
17
  * the router gets a `sendMessage(raw)` fn that calls
@@ -38,6 +38,8 @@ import type {EventSubscription} from "expo-modules-core"
38
38
 
39
39
  import devServerBridge from "./DevServerBridge"
40
40
  import type localMiniappRuntime from "./LocalMiniappRuntime"
41
+ import type {MiniappLaunchSource} from "@glassly/miniapp"
42
+
41
43
  import type {InstalledMiniappManifest} from "./LocalMiniappRuntime"
42
44
  import type {JSCrashController} from "./JSCrashController"
43
45
  import {JSLogRingBuffer, JSLogThrottle, redactSecrets} from "./JSLogPipeline"
@@ -45,6 +47,8 @@ import {islandNotifications} from "./NotificationsEmitter"
45
47
  import type {UIRouter} from "./UIRouter"
46
48
  import {miniappRunningRegistry} from "./MiniappRunningRegistry"
47
49
 
50
+ import {BgTimer} from "../utils/timers"
51
+
48
52
  /** The runtime's runtime instance type — the singleton exported from
49
53
  * LocalMiniappRuntime.ts (the file's `export default` is the instance,
50
54
  * not the class).
@@ -96,6 +100,7 @@ interface SpawnCache {
96
100
  miniappJs: string
97
101
  permissions: string[]
98
102
  installedManifest?: InstalledMiniappManifest
103
+ launchSource?: MiniappLaunchSource
99
104
  }
100
105
 
101
106
  export class JSRouter {
@@ -104,7 +109,7 @@ export class JSRouter {
104
109
  /** Cached spawn arguments so the crash controller can respawn after a backoff. */
105
110
  private readonly spawnCache: Map<string, SpawnCache> = new Map()
106
111
  /** Active respawn timers (so unregister() can cancel a pending respawn). */
107
- private readonly respawnTimers: Map<string, ReturnType<typeof setTimeout>> = new Map()
112
+ private readonly respawnTimers: Map<string, number> = new Map()
108
113
 
109
114
  /**
110
115
  * Optional crash controller. When wired, every `__error` frame from a
@@ -148,12 +153,12 @@ export class JSRouter {
148
153
  ) {}
149
154
 
150
155
  /**
151
- * Subscribe to Crust's `glasslyjs_message` event. Idempotent — calling
156
+ * Subscribe to Crust's `js_message` event. Idempotent — calling
152
157
  * start() twice attaches a single listener.
153
158
  */
154
159
  start(): void {
155
160
  if (this.subscription) return
156
- this.subscription = this.crust.addListener("glasslyjs_message", (raw) => {
161
+ this.subscription = this.crust.addListener("js_message", (raw) => {
157
162
  try {
158
163
  this.handleOutbound(raw as unknown as OutboundMessagePayload)
159
164
  } catch (e) {
@@ -192,13 +197,18 @@ export class JSRouter {
192
197
  * (e.g. {@link spawnAndRegister} below, or the host's miniapp launch
193
198
  * pipeline) should call this once per spawn.
194
199
  */
195
- registerApp(packageName: string, installedManifest?: InstalledMiniappManifest): void {
200
+ registerApp(
201
+ packageName: string,
202
+ installedManifest?: InstalledMiniappManifest,
203
+ launchSource?: MiniappLaunchSource,
204
+ ): void {
196
205
  this.runtime.registerApp(
197
206
  packageName,
198
207
  (raw: string) => {
199
208
  this.dispatchBridgeRaw(packageName, raw)
200
209
  },
201
210
  installedManifest,
211
+ launchSource,
202
212
  )
203
213
  this.registered.add(packageName)
204
214
  // JSContext is the source-of-truth for "miniapp running". The
@@ -218,7 +228,11 @@ export class JSRouter {
218
228
  async spawnAndRegister(
219
229
  packageName: string,
220
230
  miniappJs: string,
221
- options?: {permissions?: string[]; installedManifest?: InstalledMiniappManifest},
231
+ options?: {
232
+ permissions?: string[]
233
+ installedManifest?: InstalledMiniappManifest
234
+ launchSource?: MiniappLaunchSource
235
+ },
222
236
  ): Promise<boolean> {
223
237
  if (!this.crust.jsSpawn) {
224
238
  this.logger.warn("jsSpawn not available — host binding missing native function")
@@ -243,7 +257,7 @@ export class JSRouter {
243
257
  if (options?.permissions && options.permissions.length > 0) {
244
258
  await this.crust.jsSetManifest(packageName, options.permissions)
245
259
  }
246
- this.registerApp(packageName, options?.installedManifest)
260
+ this.registerApp(packageName, options?.installedManifest, options?.launchSource)
247
261
  // Cache spawn arguments so the crash controller can respawn the
248
262
  // same code after a backoff. permissions + manifest are cached too
249
263
  // because the native side resets setManifest on every spawn and
@@ -253,6 +267,7 @@ export class JSRouter {
253
267
  miniappJs,
254
268
  permissions: options?.permissions ?? [],
255
269
  installedManifest: options?.installedManifest,
270
+ launchSource: options?.launchSource,
256
271
  })
257
272
  this.crashController?.onSpawn(packageName)
258
273
 
@@ -299,8 +314,8 @@ export class JSRouter {
299
314
  if (outcome.scheduleRespawnAfterMs == null) return
300
315
  // Cancel any prior pending respawn before scheduling a new one.
301
316
  const existing = this.respawnTimers.get(packageName)
302
- if (existing) clearTimeout(existing)
303
- const timer = setTimeout(() => {
317
+ if (existing) BgTimer.clearTimeout(existing)
318
+ const timer = BgTimer.setTimeout(() => {
304
319
  this.respawnTimers.delete(packageName)
305
320
  void (async () => {
306
321
  try {
@@ -316,7 +331,7 @@ export class JSRouter {
316
331
  if (cached.permissions.length > 0) {
317
332
  await this.crust.jsSetManifest(packageName, cached.permissions)
318
333
  }
319
- this.registerApp(packageName, cached.installedManifest)
334
+ this.registerApp(packageName, cached.installedManifest, cached.launchSource)
320
335
  controller.onSpawn(packageName)
321
336
  // Re-fire the init envelope so the respawned context's
322
337
  // `registerMiniapp` handler runs again.
@@ -346,7 +361,7 @@ export class JSRouter {
346
361
  // want a stale timer to re-spawn a miniapp the user just disabled.
347
362
  const pending = this.respawnTimers.get(packageName)
348
363
  if (pending) {
349
- clearTimeout(pending)
364
+ BgTimer.clearTimeout(pending)
350
365
  this.respawnTimers.delete(packageName)
351
366
  }
352
367
  this.spawnCache.delete(packageName)
@@ -389,7 +404,7 @@ export class JSRouter {
389
404
  private handleOutbound(msg: OutboundMessagePayload): void {
390
405
  const {packageName, iface, method} = msg
391
406
  if (!packageName || !iface || !method) {
392
- this.logger.warn(`bad glasslyjs_message — missing fields`, msg)
407
+ this.logger.warn(`bad js_message — missing fields`, msg)
393
408
  return
394
409
  }
395
410
 
@@ -453,7 +468,7 @@ export class JSRouter {
453
468
  this.logRing.push(packageName, line)
454
469
  // Forward to the `glassly-miniapp dev` sidecar (if one is connected
455
470
  // for this package). Source="background" so the CLI tags lines as
456
- // [GlasslyJS]. The bridge silently drops when no dev server is up,
471
+ // [JSRuntime]. The bridge silently drops when no dev server is up,
457
472
  // which makes this safe to call unconditionally in prod.
458
473
  const argsForBridge = Array.isArray(safeArgs) ? (safeArgs as unknown[]) : [safeArgs]
459
474
  devServerBridge.forwardLog(packageName, method, argsForBridge, Date.now(), "background")
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * Scope is deliberately local-only. Cloud-originated displays are untouched
13
13
  * and may race with local displays during dev; that's acceptable per plan
14
- * (agents/local-display-manager-plan.md).
14
+ * (notes/archive/agents/local-display-manager-plan.md).
15
15
  *
16
16
  * Display pacing is NOT done here. A JS-side ~300ms throttle used to live in
17
17
  * this class, but JS timers (and therefore the throttle's trailing flush) do
@@ -29,7 +29,8 @@
29
29
  import BluetoothSdk from "@glassly/bluetooth-sdk/internal"
30
30
  import displayProcessor from "./DisplayProcessor"
31
31
  import {useDisplayStore} from "../stores/display"
32
- import sceneRenderer from "./SceneRenderer"
32
+ import sceneRenderer, {type SceneEmitResult} from "./SceneRenderer"
33
+ import dashboardOpenTrace from "./debug/DashboardOpenTrace"
33
34
  import {isGlassesConnected} from "./GlassesReadiness"
34
35
  import {useGlassesStore} from "../stores/glasses"
35
36
  import type {SceneElementInput} from "../utils/display/scene"
@@ -53,6 +54,10 @@ export interface DisplayRequestResult {
53
54
  status: "displayed" | "blocked"
54
55
  degraded?: boolean
55
56
  dropped?: string[]
57
+ /** Scene frames: the glasses had the frame (and finished its transitions) before this resolved. */
58
+ presented?: boolean
59
+ /** A newer frame from the same app settled this one. */
60
+ superseded?: boolean
56
61
  reason?: string
57
62
  }
58
63
 
@@ -99,6 +104,10 @@ const SYSTEM_BOOT_PKG = "system.boot"
99
104
  // Sentinel package for transient OS notices (quota exhausted, etc.).
100
105
  const SYSTEM_NOTICE_PKG = "system.notice"
101
106
  const SYSTEM_NOTICE_DURATION_MS = 6_000
107
+ // A scene frame native never reports on (page rebuilding, link stalled)
108
+ // resolves presented:false after this — long enough for a full-frame BLE
109
+ // image transfer with retries, short enough that an awaiting app isn't stuck.
110
+ const PRESENTATION_TIMEOUT_MS = 3_000
102
111
 
103
112
  /** "Render nothing" — an empty scene or an explicit clear_view layout. */
104
113
  function isClearPayload(payload: DisplayPayload): boolean {
@@ -153,8 +162,8 @@ class LocalDisplayManager {
153
162
  private bootingApp: BootingApp | null = null
154
163
  private bootQueue: Map<string, {payload: DisplayPayload; resolve?: DisplayRequestResolver}> = new Map()
155
164
 
156
- /** While true the dashboard owns the glasses: main frames are retained but not sent. */
157
- private dashboardActive = false
165
+ /** The page holding the overlay slot; while set, main frames are retained but not sent. */
166
+ private overlayOwner: string | null = null
158
167
 
159
168
  /** Miniapp whose visible frame is temporarily covered by an OS exit notice. */
160
169
  private exitingApp: {packageName: string; coveredDisplay: ActiveDisplay} | null = null
@@ -268,7 +277,7 @@ class LocalDisplayManager {
268
277
 
269
278
  /**
270
279
  * The package that currently owns the glasses screen, for gesture-claim
271
- * arbitration (see LocalMiniappRuntime.foregroundClaimsGesture). This is
280
+ * arbitration (the double-tap exit rule in GlassesTouchInput). This is
272
281
  * glasses ownership, not the phone's Compositor foreground: a background
273
282
  * miniapp rendering to the glasses with the phone pocketed is the owner.
274
283
  *
@@ -293,6 +302,8 @@ class LocalDisplayManager {
293
302
  * and therefore must not be closed by the system double-tap gesture.
294
303
  */
295
304
  public getVisibleMiniappPackageName(): string | null {
305
+ // Main content is retained while an overlay covers it, but is not visible.
306
+ if (this.overlayOwner !== null) return null
296
307
  const current = this.currentDisplay?.packageName ?? null
297
308
  if (!current || current === SYSTEM_BOOT_PKG || current === SYSTEM_NOTICE_PKG) return null
298
309
  return current
@@ -348,6 +359,12 @@ class LocalDisplayManager {
348
359
  }
349
360
  }
350
361
 
362
+ /** The foreground (core) miniapp is drawing on the glasses right now. */
363
+ public foregroundAppOnScreen(): boolean {
364
+ const current = this.currentDisplay
365
+ return current !== null && this.coreApp !== null && current.packageName === this.coreApp
366
+ }
367
+
351
368
  /** Report-safe ownership snapshot for incident diagnostics. */
352
369
  public getDiagnosticSnapshot(): Record<string, unknown> {
353
370
  return {
@@ -430,12 +447,27 @@ class LocalDisplayManager {
430
447
  * Dashboard cover state. On deactivate the retained main frame repaints
431
448
  * (scenes replay create-based; legacy re-sends), or the glasses clear.
432
449
  */
433
- public setDashboardActive(active: boolean): void {
434
- if (this.dashboardActive === active) return
435
- this.dashboardActive = active
436
- useDisplayStore.getState().setDashboardActive(active)
437
- if (active) return
438
- sceneRenderer.markViewStale("dashboard")
450
+ /** The page holding the overlay slot, or null while the main content shows. */
451
+ public getOverlayOwner(): string | null {
452
+ return this.overlayOwner
453
+ }
454
+
455
+ /**
456
+ * Hand the overlay slot to `owner` (a page's scene app id) or release it.
457
+ * A new owner replaces the previous page: its retained scene is dropped so
458
+ * the first frame paints from empty. Releasing replays the retained main
459
+ * content, or clears when it has expired.
460
+ */
461
+ public setOverlayOwner(owner: string | null): void {
462
+ const previous = this.overlayOwner
463
+ if (previous === owner) return
464
+ this.overlayOwner = owner
465
+ useDisplayStore.getState().setOverlayOwner(owner)
466
+ if (previous !== null) {
467
+ sceneRenderer.markViewStale("dashboard")
468
+ sceneRenderer.clearApp(previous)
469
+ }
470
+ if (owner !== null) return
439
471
  const current = this.currentDisplay
440
472
  if (current && (current.expiresAt === null || this.now() < current.expiresAt)) {
441
473
  this.replayCurrent()
@@ -444,14 +476,37 @@ class LocalDisplayManager {
444
476
  }
445
477
  }
446
478
 
447
- /** Dashboard renderers only; bypasses arbitration and main ownership state. */
448
- public renderDashboard(packageName: string, payload: DisplayPayload): void {
449
- if (!this.dashboardActive) return
479
+ /**
480
+ * The overlay slot only; bypasses arbitration and main ownership state.
481
+ * Frames from an owner other than the slot's are dropped. Returns the scene
482
+ * frame's seq (0 when nothing went to the glasses). With `resolve` (an
483
+ * awaited render from the designated miniapp) the outcome settles the way
484
+ * a main frame's does: `presented` once the glasses have the frame, or
485
+ * false at once when the slot is not this owner's.
486
+ */
487
+ public renderOverlay(packageName: string, payload: DisplayPayload, resolve?: DisplayRequestResolver): number {
488
+ if (this.overlayOwner !== packageName) {
489
+ resolve?.({status: "displayed", presented: false, reason: "dashboard view not showing"})
490
+ return 0
491
+ }
450
492
  if (payload.scene) {
451
- sceneRenderer.emitScene(packageName, "dashboard", payload.scene)
452
- return
493
+ const result = sceneRenderer.emitScene(packageName, "dashboard", payload.scene)
494
+ if (result.kind === "no-display") {
495
+ resolve?.({status: "blocked", reason: "no display connected"})
496
+ return 0
497
+ }
498
+ if (result.kind === "legacy") {
499
+ resolve?.({status: "displayed", degraded: result.degraded, dropped: result.dropped})
500
+ return 0
501
+ }
502
+ if (resolve) this.settleScene(packageName, result, resolve)
503
+ if (result.sent) dashboardOpenTrace.frameSent(result.seq)
504
+ return result.sent ? result.seq : 0
505
+ }
506
+ if (!payload.layout) {
507
+ resolve?.({status: "displayed", presented: false, reason: "empty frame"})
508
+ return 0
453
509
  }
454
- if (!payload.layout) return
455
510
  const rawEvent = {view: "dashboard", layout: payload.layout}
456
511
  let processedEvent: Record<string, unknown>
457
512
  try {
@@ -461,6 +516,8 @@ class LocalDisplayManager {
461
516
  processedEvent = rawEvent
462
517
  }
463
518
  this.pushToNative(processedEvent)
519
+ resolve?.({status: "displayed"})
520
+ return 0
464
521
  }
465
522
 
466
523
  // ===========================================================================
@@ -484,11 +541,10 @@ class LocalDisplayManager {
484
541
  return
485
542
  }
486
543
 
487
- // Dashboard view: only visible while the dashboard covers the glasses.
488
- // Local miniapp dashboard content remains a stub.
544
+ // The overlay slot: only its owner (the designated dashboard miniapp,
545
+ // under its package name) draws there; anyone else's frame is dropped.
489
546
  if (payload.view === "dashboard") {
490
- this.renderDashboard(packageName, payload)
491
- resolve?.({status: "displayed"})
547
+ this.renderOverlay(packageName, payload, resolve)
492
548
  return
493
549
  }
494
550
 
@@ -717,7 +773,37 @@ class LocalDisplayManager {
717
773
  this.handleExpiry(packageName)
718
774
  }, delay)
719
775
  }
720
- resolve?.({status: "displayed", degraded: result.degraded, dropped: result.dropped})
776
+ if (!resolve) return
777
+ this.settleScene(packageName, result, resolve)
778
+ }
779
+
780
+ /**
781
+ * Settle an awaited render() once the glasses have the frame and its
782
+ * transitions have played out. A frame that stayed phone-side (the other
783
+ * view is showing) settles at once with `presented: false`. The timeout
784
+ * keeps a frame the device never reports on from hanging the app.
785
+ */
786
+ private settleScene(
787
+ packageName: string,
788
+ result: Extract<SceneEmitResult, {kind: "scene"}>,
789
+ resolve: DisplayRequestResolver,
790
+ ): void {
791
+ const base = {status: "displayed" as const, degraded: result.degraded, dropped: result.dropped}
792
+ if (!result.sent) {
793
+ resolve({...base, presented: false, reason: "dashboard active"})
794
+ return
795
+ }
796
+ void sceneRenderer.whenPresented(result.seq, PRESENTATION_TIMEOUT_MS, packageName).then((p) => {
797
+ const finish = () =>
798
+ resolve({
799
+ ...base,
800
+ presented: p.presented,
801
+ ...(p.superseded ? {superseded: true} : {}),
802
+ ...(p.reason !== undefined ? {reason: p.reason} : {}),
803
+ })
804
+ if (p.presented && result.settleMs > 0) BgTimer.setTimeout(finish, result.settleMs)
805
+ else finish()
806
+ })
721
807
  }
722
808
 
723
809
  private sendToNative(packageName: string, rawEvent: Record<string, unknown>, expiresAt: number | null): void {
@@ -729,9 +815,9 @@ class LocalDisplayManager {
729
815
  processedEvent = rawEvent
730
816
  }
731
817
 
732
- // While the dashboard covers the glasses, main frames only update the
733
- // retained state; setDashboardActive(false) replays the latest.
734
- if (!this.dashboardActive) this.pushToNative(processedEvent)
818
+ // While a page holds the overlay slot, main frames only update the
819
+ // retained state; setOverlayOwner(null) replays the latest.
820
+ if (this.overlayOwner === null) this.pushToNative(processedEvent)
735
821
 
736
822
  this.currentDisplay = {packageName, processedEvent, expiresAt}
737
823
 
@@ -964,7 +1050,7 @@ class LocalDisplayManager {
964
1050
  this.currentDisplay = null
965
1051
  this.backgroundLock = null
966
1052
  this.exitingApp = null
967
- this.dashboardActive = false
1053
+ this.overlayOwner = null
968
1054
  this.bootQueue.clear()
969
1055
  this.now = () => Date.now()
970
1056
  this.unsubscribeGlassesStatus?.()
@@ -12,7 +12,7 @@
12
12
  * - SimpleStorage `localstorage_{userId}_{pkg}_{key}`
13
13
  * - blob metadata `blobmeta_{userId}_{pkg}_{key}`
14
14
  * - memory store `memory_{userId}_{log|summaries}`
15
- * Blob *file* bytes live under a `{documents}/glassly_blobs/{userId}/` dir and
15
+ * Blob *file* bytes live under a `{documents}/blobs/{userId}/` dir and
16
16
  * are moved by the caller (see migrateLocalBlobFiles) — this module stays
17
17
  * dependency-free so it can be unit-tested without a filesystem.
18
18
  *