@glassly/engine 0.1.0-dev.98 → 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
@@ -20,39 +20,60 @@ import BluetoothSdk from "@glassly/bluetooth-sdk/internal"
20
20
  import {shallow} from "zustand/shallow"
21
21
 
22
22
  import localMiniappRuntime from "./LocalMiniappRuntime"
23
- import localDisplayManager from "./LocalDisplayManager"
23
+ import glassesKeyboardInput from "./GlassesKeyboardInput"
24
+ import glassesSensorService from "./GlassesSensorService"
24
25
  import localSttFallbackCoordinator from "./LocalSttFallbackCoordinator"
25
- import {MiniappExitGesture} from "./MiniappExitGesture"
26
- import nativeNavigationService from "./NativeNavigationService"
27
26
  import speakerLabelResolver from "./SpeakerLabelResolver"
28
27
  import {phonePhotoCoordinator} from "./PhonePhotoCoordinator"
29
28
  import {phoneStreamCoordinator} from "./PhoneStreamCoordinator"
30
29
  import {isGlassesConnected} from "./GlassesReadiness"
31
30
  import {useGlassesStore} from "../stores/glasses"
32
- import {SETTINGS, useSettingsStore} from "../stores/settings"
31
+ import {useSettingsStore} from "../stores/settings"
33
32
  import {useAppStatusStore} from "../stores/apps"
34
33
  import {retirePendingSelectionOnPromotion} from "./PairingIdentity"
35
34
  import GlobalEventEmitter from "../utils/GlobalEventEmitter"
36
- import {BgTimer} from "../utils/timers"
37
35
  import {asgCameraApi} from "./asg/asgCameraApi"
38
- import dashboardCoordinator from "./DashboardCoordinator"
39
- import gestureDotsService from "./GestureDotsService"
36
+ import {dispatchTouchEvent, resetTouchInput} from "./GlassesTouchInput"
37
+ import dashboardOpenTrace from "./debug/DashboardOpenTrace"
40
38
 
41
39
  let subs: Array<{remove: () => void}> = []
42
40
 
43
- const miniappExitGesture = new MiniappExitGesture({
44
- getState: () => useAppStatusStore.getState(),
45
- getVisiblePackageName: () => localDisplayManager.getVisibleMiniappPackageName(),
46
- beginExitNotice: (packageName, text) => localDisplayManager.beginMiniappExit(packageName, text),
47
- finishExitNotice: (packageName) => localDisplayManager.finishMiniappExit(packageName),
48
- cancelExitNotice: (packageName) => localDisplayManager.cancelMiniappExit(packageName),
49
- setTimeout: (callback, delay) => BgTimer.setTimeout(callback, delay),
50
- clearTimeout: (timerId) => BgTimer.clearTimeout(timerId),
51
- })
52
-
53
41
  export function startDeviceEventRouter(): void {
54
42
  if (subs.length) return
55
43
 
44
+ subs.push(
45
+ BluetoothSdk.addListener("light_sensor", ({type: _type, ...reading}) => {
46
+ localMiniappRuntime.forwardEvent("light_sensor", reading)
47
+ }),
48
+ // Stock firmware emits these only inside its nav UI; custom firmware whenever the
49
+ // raw compass runs. Either way they feed the one session.compass stream.
50
+ BluetoothSdk.addListener("compass_heading", ({type: _type, heading, ...reading}) => {
51
+ localMiniappRuntime.forwardEvent("glasses_compass", {degrees: heading, ...reading})
52
+ }),
53
+ BluetoothSdk.addListener("compass_calibration", ({type: _type, ...reading}) => {
54
+ localMiniappRuntime.forwardEvent("compass_calibration", reading)
55
+ }),
56
+ {
57
+ remove: useGlassesStore.subscribe(
58
+ (s) => s.connection,
59
+ (connection) => {
60
+ if (isGlassesConnected(connection)) void glassesSensorService.resync()
61
+ else glassesSensorService.disconnected()
62
+ },
63
+ ),
64
+ },
65
+ {
66
+ // CFW classification lands after device-ready; compass demand recorded before
67
+ // that only reaches the firmware once the scene canvas is published.
68
+ remove: useGlassesStore.subscribe(
69
+ (s) => s.sceneCanvasWidth,
70
+ (width) => {
71
+ if ((width ?? 0) > 0) void glassesSensorService.resync()
72
+ },
73
+ ),
74
+ },
75
+ )
76
+
56
77
  // --- device state → engine stores ---
57
78
 
58
79
  // Standalone WiFi status → glasses store.
@@ -82,17 +103,28 @@ export function startDeviceEventRouter(): void {
82
103
  ),
83
104
  })
84
105
 
85
- // Incremental battery status → glasses store + local miniapps.
106
+ // Battery streams follow the store, including initial native hydration and
107
+ // onGlassesStatus patches. G2 can report its level without battery_status;
108
+ // forwarding only that legacy event leaves a running dashboard ring-only.
109
+ subs.push({
110
+ remove: useGlassesStore.subscribe(
111
+ (s) => ({level: s.batteryLevel, charging: s.charging}),
112
+ (battery) => {
113
+ localMiniappRuntime.forwardEvent("glasses_battery_update", {
114
+ type: "glasses_battery_update",
115
+ ...battery,
116
+ timestamp: Date.now(),
117
+ })
118
+ },
119
+ {equalityFn: shallow},
120
+ ),
121
+ })
122
+
123
+ // Legacy standalone events feed the same store subscription.
86
124
  subs.push(
87
125
  BluetoothSdk.addListener("battery_status", (event) => {
88
126
  const state = useGlassesStore.getState()
89
127
  state.setBatteryInfo(event.level, event.charging, state.caseBatteryLevel, state.caseCharging)
90
- localMiniappRuntime.forwardEvent("glasses_battery_update", {
91
- type: "glasses_battery_update",
92
- level: event.level,
93
- charging: event.charging,
94
- timestamp: event.timestamp ?? Date.now(),
95
- })
96
128
  }),
97
129
  )
98
130
 
@@ -196,53 +228,18 @@ export function startDeviceEventRouter(): void {
196
228
  localMiniappRuntime.forwardEvent("button_press", event)
197
229
  }),
198
230
  )
199
- subs.push(
200
- BluetoothSdk.addListener("touch_event", (event) => {
201
- // While the custom dashboard is visible it owns its focus/navigation
202
- // gestures; do not leak those into a miniapp running underneath it.
203
- if (dashboardCoordinator.handleGesture(event.gestureName)) return
204
-
205
- // Gesture-dots debug indicator (any device, gated by its setting). It
206
- // only paints while the screen is otherwise empty; the gesture still
207
- // flows to miniapps below.
208
- gestureDotsService.noteGesture(event.gestureName)
209
-
210
- localMiniappRuntime.forwardEvent("touch_event", event)
211
- // Double-tap policy, moved out of the native G2 handlers: exit a visible
212
- // unclaimed miniapp; otherwise open the dashboard or toggle head-up.
213
- // Native only reports the gesture now.
214
- if (event.gestureName === "double_tap") {
215
- // A foreground miniapp that claimed double_tap (CLAIM_GESTURES) is
216
- // using it as an in-app gesture (e.g. the terminal's back-to-menu) —
217
- // the event was already forwarded above; skip the system default.
218
- if (localMiniappRuntime.foregroundClaimsGesture("double_tap")) return
219
-
220
- // An unclaimed double tap exits only the miniapp whose frame is visibly
221
- // on the glasses. The controller shows the bounded OS notice first,
222
- // then uses the normal store stop path (and closes its phone overlay).
223
- // Checked before the dashboard toggle: while an app owns the screen an
224
- // unclaimed double-tap always means "leave the app" — the (custom or
225
- // native) dashboard is for the empty screen, and head-up still opens
226
- // the custom dashboard mid-app.
227
- if (miniappExitGesture.tryExitVisibleMiniapp()) return
228
-
229
- // Eligible G2 custom firmware replaces the native dashboard.
230
- if (dashboardCoordinator.toggleCustom()) return
231
-
232
- const useNativeDashboard = useSettingsStore.getState().getSetting(SETTINGS.use_native_dashboard.key) !== false
233
- if (useNativeDashboard) {
234
- // The modal nav UI owns the screen; showDashboard would fight it.
235
- if (!nativeNavigationService.isActive) {
236
- void Promise.resolve(BluetoothSdk.showDashboard()).catch((err) => {
237
- console.error("DeviceEventRouter: showDashboard failed:", err)
238
- })
239
- }
240
- } else {
241
- dashboardCoordinator.toggleLegacy()
242
- }
243
- }
244
- }),
245
- )
231
+ subs.push(BluetoothSdk.addListener("touch_event", dispatchTouchEvent))
232
+ // Physical keyboard bridged through G2 Glassly CFW: raw HID transitions →
233
+ // layout-translated keyboard_event stream (with synthesized auto-repeat).
234
+ subs.push(BluetoothSdk.addListener("keyboard_key", (event) => glassesKeyboardInput.handle(event)))
235
+ subs.push({
236
+ remove: useGlassesStore.subscribe(
237
+ (s) => s.keyboardConnected === true,
238
+ (connected) => {
239
+ if (!connected) glassesKeyboardInput.reset()
240
+ },
241
+ ),
242
+ })
246
243
  // G2 IMU accelerometer — payload already matches the miniapp AccelData shape.
247
244
  subs.push(
248
245
  BluetoothSdk.addListener("accel_event", (event) => {
@@ -255,12 +252,14 @@ export function startDeviceEventRouter(): void {
255
252
  }),
256
253
  )
257
254
  // Head position — translate native {up:boolean} → SDK {position:"up"|"down"}.
255
+ // The dashboard miniapp opens on head-up from this stream (ADR-0006).
258
256
  subs.push(
259
257
  BluetoothSdk.addListener("head_up", (event) => {
260
- dashboardCoordinator.setHeadUp(event.up)
258
+ if (event.up) dashboardOpenTrace.trigger("head-up")
261
259
  localMiniappRuntime.forwardEvent("head_up", {position: event.up ? "up" : "down", timestamp: Date.now()})
262
260
  }),
263
261
  )
262
+ subs.push({remove: dashboardOpenTrace.start()})
264
263
  // On-device STT transcripts → local miniapps only while the local engine is
265
264
  // active (cloud fallback or an explicit forceLocal subscription). The runtime
266
265
  // filters mixed local/cloud delivery per miniapp to avoid double-delivery.
@@ -293,7 +292,7 @@ export function startDeviceEventRouter(): void {
293
292
  if (app.running) {
294
293
  useAppStatusStore.getState().stop(packageName)
295
294
  } else {
296
- useAppStatusStore.getState().start(app, {skipNavigation: true})
295
+ useAppStatusStore.getState().start(app, {skipNavigation: true, launchSource: "glasses"})
297
296
  }
298
297
  }),
299
298
  )
@@ -302,5 +301,5 @@ export function startDeviceEventRouter(): void {
302
301
  export function stopDeviceEventRouter(): void {
303
302
  for (const sub of subs) sub.remove()
304
303
  subs = []
305
- miniappExitGesture.reset()
304
+ resetTouchInput()
306
305
  }
@@ -0,0 +1,107 @@
1
+ import type {DisplayDiagnostic} from "@glassly/miniapp"
2
+
3
+ // Explicit allowlist: the diagnostics API must never expose ordinary console
4
+ // messages, packet bytes, or arbitrary application content to another miniapp.
5
+ const fields = new Set([
6
+ "v",
7
+ "run",
8
+ "id",
9
+ "t",
10
+ "type",
11
+ "app",
12
+ "seq",
13
+ "page",
14
+ "pageGeneration",
15
+ "qL",
16
+ "qR",
17
+ "payloadQueue",
18
+ "pendingFrame",
19
+ "cfw",
20
+ "mic",
21
+ "background",
22
+ "fpsLimit",
23
+ "windowMs",
24
+ "txBytes",
25
+ "txPackets",
26
+ "txBytesL",
27
+ "txBytesR",
28
+ "framesIn",
29
+ "framesEncoded",
30
+ "framesAcked",
31
+ "coalesced",
32
+ "errors",
33
+ "timeouts",
34
+ "nacks",
35
+ "resync",
36
+ "vectorFrames",
37
+ "rasterFrames",
38
+ "noop",
39
+ "fragments",
40
+ "elements",
41
+ "animatedElements",
42
+ "payloadBytes",
43
+ "uploadBytes",
44
+ "encodeErrors",
45
+ "stockTextWrites",
46
+ "stockTextBytes",
47
+ "imuSamples",
48
+ "session",
49
+ "fragment",
50
+ "fragments",
51
+ "mode",
52
+ "bytes",
53
+ "totalMs",
54
+ "result",
55
+ "written",
56
+ "attempt",
57
+ "stage",
58
+ "ok",
59
+ "mtuL",
60
+ "mtuR",
61
+ "encodeMs",
62
+ "vectorFallback",
63
+ ])
64
+ const timing =
65
+ /^(creditWaitMs[LR]|writeQueueMs|transferMs|submitMs|writeMs|ackMs|resumeMs|frameMs|encodeMs|frameQueueMs)(Avg|Max|Total)$/
66
+
67
+ export function collectDisplayDiagnostics(
68
+ entries: readonly {message: string}[],
69
+ now = Date.now(),
70
+ ): DisplayDiagnostic[] {
71
+ const records: DisplayDiagnostic[] = []
72
+ const seen = new Set<string>()
73
+ for (let i = entries.length - 1; i >= 0 && records.length < 180; i--) {
74
+ const message = entries[i].message
75
+ const offset = message.indexOf("G2PERF ")
76
+ if (offset < 0 || message.length > 8192) continue
77
+ try {
78
+ const raw = JSON.parse(message.slice(offset + 7))
79
+ if (
80
+ !raw ||
81
+ raw.v !== 1 ||
82
+ typeof raw.run !== "string" ||
83
+ raw.run.length > 64 ||
84
+ !Number.isSafeInteger(raw.id) ||
85
+ raw.id < 1 ||
86
+ !Number.isSafeInteger(raw.t) ||
87
+ raw.t < now - 180_000 ||
88
+ raw.t > now + 5000 ||
89
+ !["sample", "stall", "session"].includes(raw.type)
90
+ )
91
+ continue
92
+ const key = `${raw.run}:${raw.id}`
93
+ if (seen.has(key)) continue
94
+ const record: Record<string, string | number | boolean> = {}
95
+ for (const [name, value] of Object.entries(raw)) {
96
+ if (!fields.has(name) && !timing.test(name)) continue
97
+ if ((typeof value === "number" && Number.isFinite(value)) || typeof value === "boolean") record[name] = value
98
+ else if (typeof value === "string") record[name] = value.slice(0, 160)
99
+ }
100
+ records.push(record as DisplayDiagnostic)
101
+ seen.add(key)
102
+ } catch {
103
+ /* Ignore unrelated or incomplete console lines. */
104
+ }
105
+ }
106
+ return records.reverse()
107
+ }
@@ -30,17 +30,13 @@ import {
30
30
  import {ISLAND_SETTINGS_KEYS} from "../runtime/config"
31
31
  import {useGlassesStore} from "../stores/glasses"
32
32
  import {useSettingsStore} from "../stores/settings"
33
+ import {DeviceTypes} from "../types/enums"
33
34
  import {isGlassesConnected} from "./GlassesReadiness"
34
35
 
35
36
  // =============================================================================
36
37
  // Types
37
38
  // =============================================================================
38
39
 
39
- /**
40
- * Supported device models for display processing
41
- */
42
- export type DeviceModel = "g1" | "g2" | "z100" | "nex" | "mach1" | "mentra-live" | "simulated" | "unknown"
43
-
44
40
  /**
45
41
  * Display event types that we process
46
42
  */
@@ -204,48 +200,12 @@ function isBreakMode(value: unknown): value is BreakMode {
204
200
  /**
205
201
  * Map device model names to display profiles
206
202
  */
207
- const DEVICE_PROFILES: Record<DeviceModel, DisplayProfile> = {
208
- "g1": G1_PROFILE,
209
- "g2": G2_PROFILE,
210
- "z100": Z100_PROFILE,
211
- "nex": NEX_PROFILE,
212
- "mach1": Z100_PROFILE, // Mach1 uses same hardware as Vuzix Z100
213
- "mentra-live": G1_PROFILE, // Mentra Live has no display, uses G1 as fallback
214
- "simulated": G1_PROFILE, // Simulated uses G1 profile
215
- "unknown": G1_PROFILE, // Default to G1
216
- }
217
-
218
- /**
219
- * Normalize various model name strings to our DeviceModel type
220
- */
221
- function normalizeModelName(modelName: string | null | undefined): DeviceModel {
222
- if (!modelName) return "unknown"
223
-
224
- const lower = modelName.toLowerCase()
225
-
226
- if (lower.includes("g2") || lower.includes("even realities g2")) {
227
- return "g2"
228
- }
229
- if (lower.includes("g1") || lower.includes("even realities")) {
230
- return "g1"
231
- }
232
- if (lower.includes("z100") || lower.includes("vuzix")) {
233
- return "z100"
234
- }
235
- if (lower.includes("nex") || lower.includes("glassly display")) {
236
- return "nex"
237
- }
238
- if (lower.includes("mach1") || lower.includes("mach 1")) {
239
- return "mach1"
240
- }
241
- if (lower.includes("glassly live") || lower.includes("mentra-live")) {
242
- return "mentra-live"
243
- }
244
- if (lower.includes("simulated") || lower.includes("simulator")) {
245
- return "simulated"
246
- }
247
-
248
- return "unknown"
203
+ const DEVICE_PROFILES: Partial<Record<DeviceTypes, DisplayProfile>> = {
204
+ [DeviceTypes.G1]: G1_PROFILE,
205
+ [DeviceTypes.G2]: G2_PROFILE,
206
+ [DeviceTypes.Z100]: Z100_PROFILE,
207
+ [DeviceTypes.NEX]: NEX_PROFILE,
208
+ [DeviceTypes.MACH1]: Z100_PROFILE, // Mach1 uses same hardware as Vuzix Z100
249
209
  }
250
210
 
251
211
  // =============================================================================
@@ -260,7 +220,7 @@ function normalizeModelName(modelName: string | null | undefined): DeviceModel {
260
220
  * const processor = DisplayProcessor.getInstance()
261
221
  *
262
222
  * // When glasses connect
263
- * processor.setDeviceModel("Even Realities G1")
223
+ * processor.setDeviceModel(DeviceTypes.G1)
264
224
  *
265
225
  * // Process display events
266
226
  * const processed = processor.processDisplayEvent(rawEvent)
@@ -273,7 +233,7 @@ export class DisplayProcessor {
273
233
  private wrapper: TextWrapper
274
234
  private composer: ColumnComposer
275
235
  private profile: DisplayProfile
276
- private deviceModel: DeviceModel = "unknown"
236
+ private deviceModel: DeviceTypes = DeviceTypes.NONE
277
237
  private options: DisplayProcessorOptions
278
238
 
279
239
  private runtimeAttached = false
@@ -368,21 +328,21 @@ export class DisplayProcessor {
368
328
  * @param modelName - The model name from the connected glasses (e.g., "Even Realities G1")
369
329
  */
370
330
  public setDeviceModel(modelName: string | null | undefined): void {
371
- const normalizedModel = normalizeModelName(modelName)
331
+ const model = Object.values(DeviceTypes).find((deviceType) => deviceType === modelName) ?? DeviceTypes.NONE
372
332
 
373
- if (normalizedModel === this.deviceModel) {
333
+ if (model === this.deviceModel) {
374
334
  return // No change needed
375
335
  }
376
336
 
377
- this.deviceModel = normalizedModel
378
- const newProfile = DEVICE_PROFILES[normalizedModel]
337
+ this.deviceModel = model
338
+ const newProfile = DEVICE_PROFILES[model] ?? G1_PROFILE
379
339
 
380
340
  if (newProfile !== this.profile) {
381
341
  this.updateProfile(newProfile)
382
342
  }
383
343
 
384
344
  if (this.options.debug) {
385
- console.log(`[DisplayProcessor] Device model set to: ${normalizedModel} (from: ${modelName})`)
345
+ console.log(`[DisplayProcessor] Device model set to: ${model} (from: ${modelName})`)
386
346
  }
387
347
  }
388
348
 
@@ -407,7 +367,7 @@ export class DisplayProcessor {
407
367
  /**
408
368
  * Get the current device model
409
369
  */
410
- public getDeviceModel(): DeviceModel {
370
+ public getDeviceModel(): DeviceTypes {
411
371
  return this.deviceModel
412
372
  }
413
373
 
@@ -712,6 +672,11 @@ export class DisplayProcessor {
712
672
  return this.measurer.measureText(text)
713
673
  }
714
674
 
675
+ /** Rendered advance of one character on the current device's font, in canvas px. */
676
+ public measureChar(char: string): number {
677
+ return this.measurer.measureChar(char)
678
+ }
679
+
715
680
  /**
716
681
  * Check if text fits on a single line
717
682
  *
@@ -12,6 +12,7 @@
12
12
  * to ONE re-used firmware image container — flash and idle swap its bytes
13
13
  * (data-only update, no page rebuild) instead of creating/removing containers.
14
14
  */
15
+ import {useDisplayStore} from "../stores/display"
15
16
  import {SETTINGS, useSettingsStore} from "../stores/settings"
16
17
  import type {SceneElementInput} from "../utils/display/scene"
17
18
  import {BgTimer} from "../utils/timers"
@@ -24,6 +25,8 @@ const DOTS_APP_ID = "system.gesture-dots"
24
25
  const GESTURE_FLASH_MS = 700
25
26
  const MARGIN_X = 16
26
27
  const MARGIN_TOP = 10
28
+ // Off: tap_then_hold opens the side menu now.
29
+ const HOLD_GLYPH_ENABLED = false
27
30
 
28
31
  class GestureDotsService {
29
32
  private started = false
@@ -48,23 +51,40 @@ class GestureDotsService {
48
51
  // retained state when something else takes over, and clear any
49
52
  // leftover flash when the display empties again.
50
53
  localDisplayManager.onActiveDisplayChange((active) => {
51
- if (active) this.visible = false
54
+ if (active) this.relinquish()
52
55
  else this.render()
53
56
  }),
57
+ // Overlays do not change the retained main display's occupancy.
58
+ useDisplayStore.subscribe(
59
+ (state) => state.overlayOwner,
60
+ (owner) => {
61
+ if (owner !== null) this.relinquish()
62
+ },
63
+ ),
54
64
  )
55
65
  }
56
66
 
57
67
  stop(): void {
58
68
  for (const unsub of this.unsubs) unsub()
59
69
  this.unsubs = []
70
+ this.relinquish()
71
+ this.started = false
72
+ }
73
+
74
+ private resetGesture(): void {
60
75
  if (this.flashTimer !== null) BgTimer.clearTimeout(this.flashTimer)
61
76
  this.flashTimer = null
62
77
  this.flash = null
63
78
  this.held = false
64
79
  this.holdRecognized = false
80
+ }
81
+
82
+ /** Another surface owns the display; forget the indicator without painting over it. */
83
+ private relinquish(): void {
84
+ this.resetGesture()
65
85
  this.visible = false
66
- this.started = false
67
86
  sceneRenderer.clearApp(DOTS_APP_ID)
87
+ this.trace("relinquish")
68
88
  }
69
89
 
70
90
  private enabled(): boolean {
@@ -72,32 +92,48 @@ class GestureDotsService {
72
92
  }
73
93
 
74
94
  /**
75
- * Flash a gesture on the indicator. Other gesture names are ignored. The
76
- * device-event router calls this after the CFW dashboard had its chance to
77
- * consume the gesture, so dashboard navigation does not flash.
95
+ * Flash a gesture on the indicator. Other gesture names are ignored.
96
+ * Claimed gestures cancel any earlier press/flash without starting a new
97
+ * one: the claimant may also consume the release edge.
78
98
  */
79
- noteGesture(gestureName: string): void {
99
+ noteGesture(gestureName: string, claimed = false): void {
80
100
  if (!this.started || !this.enabled()) return
101
+ this.applyGesture(gestureName, claimed)
102
+ this.trace("input", {gestureName, claimed})
103
+ }
104
+
105
+ private applyGesture(gestureName: string, claimed: boolean): void {
106
+ if (localDisplayManager.hasActiveDisplay() || useDisplayStore.getState().overlayOwner !== null) {
107
+ this.relinquish()
108
+ return
109
+ }
110
+ if (claimed) {
111
+ this.resetGesture()
112
+ this.render()
113
+ return
114
+ }
81
115
  // Tap edges show a steady circle for as long as the finger is down (on
82
116
  // CFW these arrive for holds: ET_LONG/ET_REL forwarded as
83
- // tap_start/tap_end), with no timer — tap_end clears it.
84
- if (gestureName === "tap_start" || gestureName === "tap_end") {
85
- const held = gestureName === "tap_start"
117
+ // tap_start/tap_end), with no timer — tap_end clears it. The ring's
118
+ // touch_down is the same finger-down edge; the ring's tap_end releases it.
119
+ if (gestureName === "tap_start" || gestureName === "touch_down" || gestureName === "tap_end") {
120
+ const held = gestureName !== "tap_end"
86
121
  if (this.held === held) return
87
122
  this.held = held
88
123
  if (!held) this.holdRecognized = false
89
124
  this.render()
90
125
  return
91
126
  }
92
- // CFW tap-then-hold (the stock Menu gesture): swap the steady dot for the
93
- // bullseye until release. Recognition arrives mid-press, but set held too
94
- // in case the tap_start edge was missed — the release edge still clears.
95
- if (gestureName === "tap_then_hold") {
127
+ if (gestureName === "tap_then_hold" && HOLD_GLYPH_ENABLED) {
96
128
  this.held = true
97
129
  this.holdRecognized = true
98
130
  this.render()
99
131
  return
100
132
  }
133
+ // Any other gesture implies the finger is up, even if tap_end was lost.
134
+ const released = this.held
135
+ this.held = false
136
+ this.holdRecognized = false
101
137
  const flash: GestureDotGlyph | null =
102
138
  gestureName === "single_tap"
103
139
  ? "dot"
@@ -106,17 +142,38 @@ class GestureDotsService {
106
142
  : gestureName === "swipe_down"
107
143
  ? "down"
108
144
  : null
109
- if (!flash) return
145
+ if (!flash) {
146
+ if (released) this.render()
147
+ return
148
+ }
110
149
  this.flash = flash
111
150
  if (this.flashTimer !== null) BgTimer.clearTimeout(this.flashTimer)
112
151
  this.flashTimer = BgTimer.setTimeout(() => {
113
152
  this.flashTimer = null
114
153
  this.flash = null
115
154
  this.render()
155
+ this.trace("flash-ended")
116
156
  }, GESTURE_FLASH_MS)
117
157
  this.render()
118
158
  }
119
159
 
160
+ /** Debug setting only; no payloads or retained history. Correlate seq with G2PERF. */
161
+ private trace(reason: string, details: Record<string, unknown> = {}): void {
162
+ if (!this.enabled()) return
163
+ console.log(
164
+ "GESTUREDOTS " +
165
+ JSON.stringify({
166
+ t: Date.now(),
167
+ reason,
168
+ held: this.held,
169
+ flash: this.flash,
170
+ overlay: useDisplayStore.getState().overlayOwner,
171
+ active: localDisplayManager.hasActiveDisplay(),
172
+ ...details,
173
+ }),
174
+ )
175
+ }
176
+
120
177
  /**
121
178
  * Paint or clear the indicator. Nothing is drawn while anything else is on
122
179
  * the glasses (miniapp frame or system screen) or when no gesture was just
@@ -130,7 +187,7 @@ class GestureDotsService {
130
187
  */
131
188
  private render(): void {
132
189
  if (!this.started) return
133
- if (localDisplayManager.hasActiveDisplay()) return
190
+ if (localDisplayManager.hasActiveDisplay() || useDisplayStore.getState().overlayOwner !== null) return
134
191
  const shown = this.flash ?? (this.held ? (this.holdRecognized ? "hold" : "dot") : null)
135
192
  if (!this.enabled()) {
136
193
  if (this.visible) {
@@ -155,7 +212,11 @@ class GestureDotsService {
155
212
  },
156
213
  ]
157
214
  this.visible = true
158
- sceneRenderer.emitScene(DOTS_APP_ID, "main", elements)
215
+ const result = sceneRenderer.emitScene(DOTS_APP_ID, "main", elements)
216
+ this.trace("render", {
217
+ glyph: shown ?? "blank",
218
+ ...(result?.kind === "scene" ? {seq: result.seq, sent: result.sent} : {}),
219
+ })
159
220
  }
160
221
  }
161
222