@mentra/engine 0.1.0-dev.0 → 3.1.0-dev.10

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 (503) hide show
  1. package/README.md +55 -18
  2. package/build/bluetooth-sdk/debug.d.ts +2 -0
  3. package/build/bluetooth-sdk/debug.d.ts.map +1 -0
  4. package/build/bluetooth-sdk/debug.js +2 -0
  5. package/build/bluetooth-sdk/debug.js.map +1 -0
  6. package/build/bluetooth-sdk/index.d.ts +3 -0
  7. package/build/bluetooth-sdk/index.d.ts.map +1 -0
  8. package/build/bluetooth-sdk/index.js +3 -0
  9. package/build/bluetooth-sdk/index.js.map +1 -0
  10. package/build/bluetooth-sdk/photo-receiver.d.ts +3 -0
  11. package/build/bluetooth-sdk/photo-receiver.d.ts.map +1 -0
  12. package/build/bluetooth-sdk/photo-receiver.js +3 -0
  13. package/build/bluetooth-sdk/photo-receiver.js.map +1 -0
  14. package/build/bluetooth-sdk/react.d.ts +2 -0
  15. package/build/bluetooth-sdk/react.d.ts.map +1 -0
  16. package/build/bluetooth-sdk/react.js +2 -0
  17. package/build/bluetooth-sdk/react.js.map +1 -0
  18. package/build/bluetooth-sdk/types.d.ts +2 -0
  19. package/build/bluetooth-sdk/types.d.ts.map +1 -0
  20. package/build/bluetooth-sdk/types.js +2 -0
  21. package/build/bluetooth-sdk/types.js.map +1 -0
  22. package/build/engine.d.ts +24 -16
  23. package/build/engine.d.ts.map +1 -1
  24. package/build/engine.js +9 -4
  25. package/build/engine.js.map +1 -1
  26. package/build/facades/dev.d.ts +3 -2
  27. package/build/facades/dev.d.ts.map +1 -1
  28. package/build/facades/dev.js +18 -12
  29. package/build/facades/dev.js.map +1 -1
  30. package/build/facades/display.d.ts +1 -1
  31. package/build/facades/display.d.ts.map +1 -1
  32. package/build/facades/display.js +1 -1
  33. package/build/facades/display.js.map +1 -1
  34. package/build/facades/gallery.js +1 -1
  35. package/build/facades/gallery.js.map +1 -1
  36. package/build/facades/glasses.d.ts +4 -13
  37. package/build/facades/glasses.d.ts.map +1 -1
  38. package/build/facades/glasses.js +21 -6
  39. package/build/facades/glasses.js.map +1 -1
  40. package/build/facades/glassesSettings.d.ts.map +1 -1
  41. package/build/facades/glassesSettings.js +1 -0
  42. package/build/facades/glassesSettings.js.map +1 -1
  43. package/build/facades/miniapps.d.ts +4 -0
  44. package/build/facades/miniapps.d.ts.map +1 -1
  45. package/build/facades/miniapps.js +5 -0
  46. package/build/facades/miniapps.js.map +1 -1
  47. package/build/facades/ota.d.ts +14 -16
  48. package/build/facades/ota.d.ts.map +1 -1
  49. package/build/facades/ota.js +22 -7
  50. package/build/facades/ota.js.map +1 -1
  51. package/build/facades/pairing.d.ts +8 -5
  52. package/build/facades/pairing.d.ts.map +1 -1
  53. package/build/facades/pairing.js +12 -10
  54. package/build/facades/pairing.js.map +1 -1
  55. package/build/facades/permissions.d.ts +10 -0
  56. package/build/facades/permissions.d.ts.map +1 -1
  57. package/build/facades/permissions.js +10 -0
  58. package/build/facades/permissions.js.map +1 -1
  59. package/build/facades/phoneNotifications.d.ts +0 -4
  60. package/build/facades/phoneNotifications.d.ts.map +1 -1
  61. package/build/facades/phoneNotifications.js +4 -14
  62. package/build/facades/phoneNotifications.js.map +1 -1
  63. package/build/facades/speech.d.ts +7 -6
  64. package/build/facades/speech.d.ts.map +1 -1
  65. package/build/facades/speech.js +1 -1
  66. package/build/facades/speech.js.map +1 -1
  67. package/build/generated/releaseMetadata.d.ts +12 -0
  68. package/build/generated/releaseMetadata.d.ts.map +1 -0
  69. package/build/generated/releaseMetadata.js +10 -0
  70. package/build/generated/releaseMetadata.js.map +1 -0
  71. package/build/index.d.ts +10 -8
  72. package/build/index.d.ts.map +1 -1
  73. package/build/index.js +6 -5
  74. package/build/index.js.map +1 -1
  75. package/build/react/MentraLiveOtaFlow.d.ts +38 -0
  76. package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
  77. package/build/react/MentraLiveOtaFlow.js +528 -0
  78. package/build/react/MentraLiveOtaFlow.js.map +1 -0
  79. package/build/react/index.d.ts +2 -0
  80. package/build/react/index.d.ts.map +1 -0
  81. package/build/react/index.js +2 -0
  82. package/build/react/index.js.map +1 -0
  83. package/build/react/useEngineSnapshot.d.ts +2 -0
  84. package/build/react/useEngineSnapshot.d.ts.map +1 -0
  85. package/build/react/useEngineSnapshot.js +14 -0
  86. package/build/react/useEngineSnapshot.js.map +1 -0
  87. package/build/runtime/bootstrap.d.ts +24 -1
  88. package/build/runtime/bootstrap.d.ts.map +1 -1
  89. package/build/runtime/bootstrap.js +17 -0
  90. package/build/runtime/bootstrap.js.map +1 -1
  91. package/build/runtime/scanQrSeam.d.ts +7 -0
  92. package/build/runtime/scanQrSeam.d.ts.map +1 -0
  93. package/build/runtime/scanQrSeam.js +16 -0
  94. package/build/runtime/scanQrSeam.js.map +1 -0
  95. package/build/services/AppRegistry.d.ts +41 -57
  96. package/build/services/AppRegistry.d.ts.map +1 -1
  97. package/build/services/AppRegistry.js +208 -144
  98. package/build/services/AppRegistry.js.map +1 -1
  99. package/build/services/AudioCloudUplink.d.ts +12 -0
  100. package/build/services/AudioCloudUplink.d.ts.map +1 -1
  101. package/build/services/AudioCloudUplink.js +22 -1
  102. package/build/services/AudioCloudUplink.js.map +1 -1
  103. package/build/services/AudioPlaybackService.d.ts +41 -2
  104. package/build/services/AudioPlaybackService.d.ts.map +1 -1
  105. package/build/services/AudioPlaybackService.js +250 -33
  106. package/build/services/AudioPlaybackService.js.map +1 -1
  107. package/build/services/BlobStore.d.ts +2 -1
  108. package/build/services/BlobStore.d.ts.map +1 -1
  109. package/build/services/BlobStore.js +17 -9
  110. package/build/services/BlobStore.js.map +1 -1
  111. package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
  112. package/build/services/CloudAudioSubscriptionSync.js +13 -1
  113. package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
  114. package/build/services/CloudClientService.d.ts +15 -0
  115. package/build/services/CloudClientService.d.ts.map +1 -1
  116. package/build/services/CloudClientService.js +93 -1
  117. package/build/services/CloudClientService.js.map +1 -1
  118. package/build/services/DeviceEventRouter.js +5 -5
  119. package/build/services/DeviceEventRouter.js.map +1 -1
  120. package/build/services/ForegroundLocationPermission.d.ts +13 -0
  121. package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
  122. package/build/services/ForegroundLocationPermission.js +12 -0
  123. package/build/services/ForegroundLocationPermission.js.map +1 -0
  124. package/build/services/GlassesSettingsSync.d.ts.map +1 -1
  125. package/build/services/GlassesSettingsSync.js +9 -3
  126. package/build/services/GlassesSettingsSync.js.map +1 -1
  127. package/build/services/GlassesStatusProjection.d.ts +2 -1
  128. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  129. package/build/services/GlassesStatusProjection.js +15 -8
  130. package/build/services/GlassesStatusProjection.js.map +1 -1
  131. package/build/services/HotspotOtaTransport.d.ts +29 -0
  132. package/build/services/HotspotOtaTransport.d.ts.map +1 -0
  133. package/build/services/HotspotOtaTransport.js +146 -0
  134. package/build/services/HotspotOtaTransport.js.map +1 -0
  135. package/build/services/HotspotShutdown.d.ts +17 -0
  136. package/build/services/HotspotShutdown.d.ts.map +1 -0
  137. package/build/services/HotspotShutdown.js +29 -0
  138. package/build/services/HotspotShutdown.js.map +1 -0
  139. package/build/services/LocalDisplayManager.d.ts +15 -0
  140. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  141. package/build/services/LocalDisplayManager.js +106 -20
  142. package/build/services/LocalDisplayManager.js.map +1 -1
  143. package/build/services/LocalMiniappRuntime.d.ts +74 -2
  144. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  145. package/build/services/LocalMiniappRuntime.js +785 -291
  146. package/build/services/LocalMiniappRuntime.js.map +1 -1
  147. package/build/services/LocalMiniappStorage.d.ts +32 -0
  148. package/build/services/LocalMiniappStorage.d.ts.map +1 -0
  149. package/build/services/LocalMiniappStorage.js +66 -0
  150. package/build/services/LocalMiniappStorage.js.map +1 -0
  151. package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
  152. package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
  153. package/build/services/LocalMiniappUserIdentity.js +43 -0
  154. package/build/services/LocalMiniappUserIdentity.js.map +1 -0
  155. package/build/services/LocalSttFallbackCoordinator.d.ts +9 -6
  156. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  157. package/build/services/LocalSttFallbackCoordinator.js +18 -12
  158. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  159. package/build/services/MicStateCoordinator.d.ts +42 -1
  160. package/build/services/MicStateCoordinator.d.ts.map +1 -1
  161. package/build/services/MicStateCoordinator.js +141 -3
  162. package/build/services/MicStateCoordinator.js.map +1 -1
  163. package/build/services/MiniappLauncher.d.ts.map +1 -1
  164. package/build/services/MiniappLauncher.js +23 -3
  165. package/build/services/MiniappLauncher.js.map +1 -1
  166. package/build/services/MiniappLiveness.d.ts +12 -0
  167. package/build/services/MiniappLiveness.d.ts.map +1 -0
  168. package/build/services/MiniappLiveness.js +16 -0
  169. package/build/services/MiniappLiveness.js.map +1 -0
  170. package/build/services/NativeHttpResponse.d.ts +3 -0
  171. package/build/services/NativeHttpResponse.d.ts.map +1 -0
  172. package/build/services/NativeHttpResponse.js +6 -0
  173. package/build/services/NativeHttpResponse.js.map +1 -0
  174. package/build/services/OtaArtifactDownloader.d.ts +65 -0
  175. package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
  176. package/build/services/OtaArtifactDownloader.js +226 -0
  177. package/build/services/OtaArtifactDownloader.js.map +1 -0
  178. package/build/services/OtaAutoChain.d.ts +34 -0
  179. package/build/services/OtaAutoChain.d.ts.map +1 -0
  180. package/build/services/OtaAutoChain.js +83 -0
  181. package/build/services/OtaAutoChain.js.map +1 -0
  182. package/build/services/OtaErrorMapping.d.ts +18 -0
  183. package/build/services/OtaErrorMapping.d.ts.map +1 -0
  184. package/build/services/OtaErrorMapping.js +63 -0
  185. package/build/services/OtaErrorMapping.js.map +1 -0
  186. package/build/services/OtaInstallCoordinator.d.ts +95 -15
  187. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  188. package/build/services/OtaInstallCoordinator.js +577 -130
  189. package/build/services/OtaInstallCoordinator.js.map +1 -1
  190. package/build/services/OtaService.d.ts.map +1 -1
  191. package/build/services/OtaService.js +8 -1
  192. package/build/services/OtaService.js.map +1 -1
  193. package/build/services/OtaUpdateCheckService.d.ts +39 -4
  194. package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
  195. package/build/services/OtaUpdateCheckService.js +138 -22
  196. package/build/services/OtaUpdateCheckService.js.map +1 -1
  197. package/build/services/PhoneCalendarHelpers.d.ts +32 -0
  198. package/build/services/PhoneCalendarHelpers.d.ts.map +1 -0
  199. package/build/services/PhoneCalendarHelpers.js +157 -0
  200. package/build/services/PhoneCalendarHelpers.js.map +1 -0
  201. package/build/services/PhoneCalendarService.d.ts +5 -0
  202. package/build/services/PhoneCalendarService.d.ts.map +1 -0
  203. package/build/services/PhoneCalendarService.js +45 -0
  204. package/build/services/PhoneCalendarService.js.map +1 -0
  205. package/build/services/PhoneCameraFovCoordinator.d.ts +30 -0
  206. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
  207. package/build/services/PhoneCameraFovCoordinator.js +194 -0
  208. package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
  209. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  210. package/build/services/PhoneNotificationsSync.js +12 -10
  211. package/build/services/PhoneNotificationsSync.js.map +1 -1
  212. package/build/services/PhonePhotoCoordinator.d.ts +26 -2
  213. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  214. package/build/services/PhonePhotoCoordinator.js +79 -9
  215. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  216. package/build/services/PhoneStreamCoordinator.d.ts +8 -1
  217. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  218. package/build/services/PhoneStreamCoordinator.js +125 -13
  219. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  220. package/build/services/PhoneVideoCoordinator.d.ts +2 -0
  221. package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
  222. package/build/services/PhoneVideoCoordinator.js +10 -0
  223. package/build/services/PhoneVideoCoordinator.js.map +1 -1
  224. package/build/services/SceneRenderer.d.ts.map +1 -1
  225. package/build/services/SceneRenderer.js +15 -0
  226. package/build/services/SceneRenderer.js.map +1 -1
  227. package/build/services/SentenceTtsPipeline.d.ts +31 -0
  228. package/build/services/SentenceTtsPipeline.d.ts.map +1 -0
  229. package/build/services/SentenceTtsPipeline.js +67 -0
  230. package/build/services/SentenceTtsPipeline.js.map +1 -0
  231. package/build/services/SupportProfileSync.d.ts +22 -0
  232. package/build/services/SupportProfileSync.d.ts.map +1 -0
  233. package/build/services/SupportProfileSync.js +213 -0
  234. package/build/services/SupportProfileSync.js.map +1 -0
  235. package/build/services/TranscriptionRouting.d.ts +12 -0
  236. package/build/services/TranscriptionRouting.d.ts.map +1 -0
  237. package/build/services/TranscriptionRouting.js +24 -0
  238. package/build/services/TranscriptionRouting.js.map +1 -0
  239. package/build/services/TtsTextSanitizer.d.ts +5 -0
  240. package/build/services/TtsTextSanitizer.d.ts.map +1 -0
  241. package/build/services/TtsTextSanitizer.js +61 -0
  242. package/build/services/TtsTextSanitizer.js.map +1 -0
  243. package/build/services/WifiAdbRequest.d.ts +17 -0
  244. package/build/services/WifiAdbRequest.d.ts.map +1 -0
  245. package/build/services/WifiAdbRequest.js +35 -0
  246. package/build/services/WifiAdbRequest.js.map +1 -0
  247. package/build/services/asg/asgCameraApi.d.ts +43 -0
  248. package/build/services/asg/asgCameraApi.d.ts.map +1 -1
  249. package/build/services/asg/asgCameraApi.js +509 -26
  250. package/build/services/asg/asgCameraApi.js.map +1 -1
  251. package/build/services/asg/cameraRollExportCoordinator.d.ts +60 -0
  252. package/build/services/asg/cameraRollExportCoordinator.d.ts.map +1 -0
  253. package/build/services/asg/cameraRollExportCoordinator.js +618 -0
  254. package/build/services/asg/cameraRollExportCoordinator.js.map +1 -0
  255. package/build/services/asg/cameraRollExportLedger.d.ts +44 -0
  256. package/build/services/asg/cameraRollExportLedger.d.ts.map +1 -0
  257. package/build/services/asg/cameraRollExportLedger.js +78 -0
  258. package/build/services/asg/cameraRollExportLedger.js.map +1 -0
  259. package/build/services/asg/galleryNotices.d.ts +1 -1
  260. package/build/services/asg/galleryNotices.d.ts.map +1 -1
  261. package/build/services/asg/galleryNotices.js.map +1 -1
  262. package/build/services/asg/galleryPathMigration.d.ts +3 -0
  263. package/build/services/asg/galleryPathMigration.d.ts.map +1 -0
  264. package/build/services/asg/galleryPathMigration.js +26 -0
  265. package/build/services/asg/galleryPathMigration.js.map +1 -0
  266. package/build/services/asg/gallerySettingsService.d.ts +1 -0
  267. package/build/services/asg/gallerySettingsService.d.ts.map +1 -1
  268. package/build/services/asg/gallerySettingsService.js +2 -0
  269. package/build/services/asg/gallerySettingsService.js.map +1 -1
  270. package/build/services/asg/gallerySyncService.d.ts.map +1 -1
  271. package/build/services/asg/gallerySyncService.js +162 -56
  272. package/build/services/asg/gallerySyncService.js.map +1 -1
  273. package/build/services/asg/galleryTransferLedger.d.ts +58 -0
  274. package/build/services/asg/galleryTransferLedger.d.ts.map +1 -0
  275. package/build/services/asg/galleryTransferLedger.js +225 -0
  276. package/build/services/asg/galleryTransferLedger.js.map +1 -0
  277. package/build/services/asg/localNetworkTransport.d.ts +15 -0
  278. package/build/services/asg/localNetworkTransport.d.ts.map +1 -0
  279. package/build/services/asg/localNetworkTransport.js +144 -0
  280. package/build/services/asg/localNetworkTransport.js.map +1 -0
  281. package/build/services/asg/localStorageService.d.ts +18 -0
  282. package/build/services/asg/localStorageService.d.ts.map +1 -1
  283. package/build/services/asg/localStorageService.js +168 -19
  284. package/build/services/asg/localStorageService.js.map +1 -1
  285. package/build/services/asg/mediaProcessingQueue.d.ts +10 -0
  286. package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -1
  287. package/build/services/asg/mediaProcessingQueue.js +193 -62
  288. package/build/services/asg/mediaProcessingQueue.js.map +1 -1
  289. package/build/services/audioPlaybackAssets.d.ts +8 -0
  290. package/build/services/audioPlaybackAssets.d.ts.map +1 -0
  291. package/build/services/audioPlaybackAssets.js +7 -0
  292. package/build/services/audioPlaybackAssets.js.map +1 -0
  293. package/build/services/gallerySyncClock.js +1 -1
  294. package/build/services/gallerySyncClock.js.map +1 -1
  295. package/build/services/glassesClockSync.d.ts.map +1 -1
  296. package/build/services/glassesClockSync.js +6 -2
  297. package/build/services/glassesClockSync.js.map +1 -1
  298. package/build/services/manifestActions.d.ts +7 -0
  299. package/build/services/manifestActions.d.ts.map +1 -0
  300. package/build/services/manifestActions.js +25 -0
  301. package/build/services/manifestActions.js.map +1 -0
  302. package/build/services/otaDisplayState.d.ts +23 -12
  303. package/build/services/otaDisplayState.d.ts.map +1 -1
  304. package/build/services/otaDisplayState.js +36 -14
  305. package/build/services/otaDisplayState.js.map +1 -1
  306. package/build/services/otaInstallPolicy.d.ts +16 -4
  307. package/build/services/otaInstallPolicy.d.ts.map +1 -1
  308. package/build/services/otaInstallPolicy.js +24 -3
  309. package/build/services/otaInstallPolicy.js.map +1 -1
  310. package/build/services/otaLegacyMapping.d.ts +1 -1
  311. package/build/services/otaLegacyMapping.d.ts.map +1 -1
  312. package/build/services/otaLegacyMapping.js.map +1 -1
  313. package/build/services/otaManifestPolicy.d.ts +14 -0
  314. package/build/services/otaManifestPolicy.d.ts.map +1 -0
  315. package/build/services/otaManifestPolicy.js +19 -0
  316. package/build/services/otaManifestPolicy.js.map +1 -0
  317. package/build/services/otaManifestUrl.d.ts +3 -0
  318. package/build/services/otaManifestUrl.d.ts.map +1 -0
  319. package/build/services/otaManifestUrl.js +38 -0
  320. package/build/services/otaManifestUrl.js.map +1 -0
  321. package/build/services/slimStreamStatus.d.ts +11 -0
  322. package/build/services/slimStreamStatus.d.ts.map +1 -1
  323. package/build/services/slimStreamStatus.js +14 -4
  324. package/build/services/slimStreamStatus.js.map +1 -1
  325. package/build/stores/apps.d.ts.map +1 -1
  326. package/build/stores/apps.js +11 -0
  327. package/build/stores/apps.js.map +1 -1
  328. package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
  329. package/build/stores/bluetoothSettingKeys.js +2 -0
  330. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  331. package/build/stores/gallerySync.d.ts +2 -0
  332. package/build/stores/gallerySync.d.ts.map +1 -1
  333. package/build/stores/gallerySync.js +2 -0
  334. package/build/stores/gallerySync.js.map +1 -1
  335. package/build/stores/glasses.d.ts.map +1 -1
  336. package/build/stores/glasses.js +3 -0
  337. package/build/stores/glasses.js.map +1 -1
  338. package/build/stores/settings.d.ts +17 -0
  339. package/build/stores/settings.d.ts.map +1 -1
  340. package/build/stores/settings.js +157 -17
  341. package/build/stores/settings.js.map +1 -1
  342. package/build/types/applet.d.ts +2 -0
  343. package/build/types/applet.d.ts.map +1 -1
  344. package/build/types/applet.js.map +1 -1
  345. package/build/types/asg.d.ts +7 -0
  346. package/build/types/asg.d.ts.map +1 -1
  347. package/build/types/asg.js.map +1 -1
  348. package/build/types/enums.d.ts +2 -25
  349. package/build/types/enums.d.ts.map +1 -1
  350. package/build/types/enums.js +2 -27
  351. package/build/types/enums.js.map +1 -1
  352. package/build/types/hardware.d.ts +4 -13
  353. package/build/types/hardware.d.ts.map +1 -1
  354. package/build/types/hardware.js +15 -3
  355. package/build/types/hardware.js.map +1 -1
  356. package/build/types/index.d.ts +2 -6
  357. package/build/types/index.d.ts.map +1 -1
  358. package/build/types/index.js +2 -6
  359. package/build/types/index.js.map +1 -1
  360. package/build/utils/configuredDevHost.d.ts +6 -0
  361. package/build/utils/configuredDevHost.d.ts.map +1 -0
  362. package/build/utils/configuredDevHost.js +19 -0
  363. package/build/utils/configuredDevHost.js.map +1 -0
  364. package/build/utils/devMiniappLaunch.d.ts +19 -8
  365. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  366. package/build/utils/devMiniappLaunch.js +144 -21
  367. package/build/utils/devMiniappLaunch.js.map +1 -1
  368. package/build/utils/diagnosticContext.d.ts.map +1 -1
  369. package/build/utils/diagnosticContext.js +15 -17
  370. package/build/utils/diagnosticContext.js.map +1 -1
  371. package/build/utils/hardware/hardware.d.ts.map +1 -1
  372. package/build/utils/hardware/hardware.js +7 -3
  373. package/build/utils/hardware/hardware.js.map +1 -1
  374. package/build/utils/miniappDiagnostics.d.ts +64 -0
  375. package/build/utils/miniappDiagnostics.d.ts.map +1 -0
  376. package/build/utils/miniappDiagnostics.js +173 -0
  377. package/build/utils/miniappDiagnostics.js.map +1 -0
  378. package/build/utils/permissions/MediaLibraryPermissions.d.ts +11 -0
  379. package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -1
  380. package/build/utils/permissions/MediaLibraryPermissions.js +27 -4
  381. package/build/utils/permissions/MediaLibraryPermissions.js.map +1 -1
  382. package/build/utils/timers/timers.d.ts.map +1 -1
  383. package/build/utils/timers/timers.js +55 -18
  384. package/build/utils/timers/timers.js.map +1 -1
  385. package/package.json +59 -31
  386. package/src/assets/silence.wav +0 -0
  387. package/src/bluetooth-sdk/debug.ts +1 -0
  388. package/src/bluetooth-sdk/index.ts +2 -0
  389. package/src/bluetooth-sdk/photo-receiver.ts +2 -0
  390. package/src/bluetooth-sdk/react.ts +1 -0
  391. package/src/bluetooth-sdk/types.ts +1 -0
  392. package/src/engine.ts +9 -4
  393. package/src/facades/dev.ts +17 -12
  394. package/src/facades/display.ts +1 -1
  395. package/src/facades/gallery.ts +1 -1
  396. package/src/facades/glasses.ts +20 -7
  397. package/src/facades/glassesSettings.ts +5 -0
  398. package/src/facades/miniapps.ts +7 -0
  399. package/src/facades/ota.ts +23 -8
  400. package/src/facades/pairing.ts +15 -11
  401. package/src/facades/permissions.ts +14 -0
  402. package/src/facades/phoneNotifications.ts +4 -13
  403. package/src/facades/speech.ts +21 -7
  404. package/src/generated/releaseMetadata.ts +20 -0
  405. package/src/index.ts +39 -13
  406. package/src/react/MentraLiveOtaFlow.tsx +856 -0
  407. package/src/react/index.ts +7 -0
  408. package/src/react/useEngineSnapshot.ts +16 -0
  409. package/src/runtime/bootstrap.ts +33 -1
  410. package/src/runtime/scanQrSeam.ts +20 -0
  411. package/src/services/AppRegistry.ts +240 -149
  412. package/src/services/AudioCloudUplink.ts +23 -1
  413. package/src/services/AudioPlaybackService.ts +287 -38
  414. package/src/services/BlobStore.ts +22 -9
  415. package/src/services/CloudAudioSubscriptionSync.ts +13 -1
  416. package/src/services/CloudClientService.ts +96 -1
  417. package/src/services/DeviceEventRouter.ts +5 -5
  418. package/src/services/ForegroundLocationPermission.ts +24 -0
  419. package/src/services/GlassesSettingsSync.ts +9 -3
  420. package/src/services/GlassesStatusProjection.ts +16 -8
  421. package/src/services/HotspotOtaTransport.ts +184 -0
  422. package/src/services/HotspotShutdown.ts +41 -0
  423. package/src/services/LocalDisplayManager.ts +112 -21
  424. package/src/services/LocalMiniappRuntime.ts +967 -346
  425. package/src/services/LocalMiniappStorage.ts +82 -0
  426. package/src/services/LocalMiniappUserIdentity.ts +46 -0
  427. package/src/services/LocalSttFallbackCoordinator.ts +19 -12
  428. package/src/services/MicStateCoordinator.ts +169 -4
  429. package/src/services/MiniappLauncher.ts +30 -3
  430. package/src/services/MiniappLiveness.ts +24 -0
  431. package/src/services/NativeHttpResponse.ts +6 -0
  432. package/src/services/OtaArtifactDownloader.ts +312 -0
  433. package/src/services/OtaAutoChain.ts +106 -0
  434. package/src/services/OtaErrorMapping.ts +80 -0
  435. package/src/services/OtaInstallCoordinator.ts +649 -144
  436. package/src/services/OtaService.ts +11 -5
  437. package/src/services/OtaUpdateCheckService.ts +181 -21
  438. package/src/services/PhoneCalendarHelpers.ts +212 -0
  439. package/src/services/PhoneCalendarService.ts +65 -0
  440. package/src/services/PhoneCameraFovCoordinator.ts +210 -0
  441. package/src/services/PhoneNotificationsSync.ts +12 -10
  442. package/src/services/PhonePhotoCoordinator.ts +116 -18
  443. package/src/services/PhoneStreamCoordinator.ts +139 -25
  444. package/src/services/PhoneVideoCoordinator.ts +11 -0
  445. package/src/services/SceneRenderer.ts +16 -0
  446. package/src/services/SentenceTtsPipeline.ts +106 -0
  447. package/src/services/SupportProfileSync.ts +218 -0
  448. package/src/services/TranscriptionRouting.ts +37 -0
  449. package/src/services/TtsTextSanitizer.ts +66 -0
  450. package/src/services/WifiAdbRequest.ts +53 -0
  451. package/src/services/asg/asgCameraApi.ts +615 -33
  452. package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
  453. package/src/services/asg/cameraRollExportLedger.ts +122 -0
  454. package/src/services/asg/galleryNotices.ts +1 -0
  455. package/src/services/asg/galleryPathMigration.ts +22 -0
  456. package/src/services/asg/gallerySettingsService.ts +3 -0
  457. package/src/services/asg/gallerySyncService.ts +184 -73
  458. package/src/services/asg/galleryTransferLedger.ts +312 -0
  459. package/src/services/asg/localNetworkTransport.ts +169 -0
  460. package/src/services/asg/localStorageService.ts +179 -24
  461. package/src/services/asg/mediaProcessingQueue.ts +209 -62
  462. package/src/services/audioPlaybackAssets.ts +8 -0
  463. package/src/services/gallerySyncClock.ts +1 -1
  464. package/src/services/glassesClockSync.ts +6 -2
  465. package/src/services/manifestActions.ts +30 -0
  466. package/src/services/otaDisplayState.ts +58 -17
  467. package/src/services/otaInstallPolicy.ts +30 -4
  468. package/src/services/otaLegacyMapping.ts +1 -1
  469. package/src/services/otaManifestPolicy.ts +42 -0
  470. package/src/services/otaManifestUrl.ts +44 -0
  471. package/src/services/slimStreamStatus.ts +16 -5
  472. package/src/stores/apps.ts +12 -0
  473. package/src/stores/bluetoothSettingKeys.ts +2 -0
  474. package/src/stores/gallerySync.ts +4 -0
  475. package/src/stores/glasses.ts +3 -0
  476. package/src/stores/settings.ts +179 -18
  477. package/src/types/applet.ts +2 -0
  478. package/src/types/asg.ts +7 -0
  479. package/src/types/enums.ts +3 -28
  480. package/src/types/hardware.ts +20 -13
  481. package/src/types/index.ts +2 -6
  482. package/src/utils/configuredDevHost.ts +17 -0
  483. package/src/utils/devMiniappLaunch.ts +151 -23
  484. package/src/utils/diagnosticContext.ts +17 -17
  485. package/src/utils/hardware/hardware.ts +7 -9
  486. package/src/utils/miniappDiagnostics.ts +226 -0
  487. package/src/utils/permissions/MediaLibraryPermissions.ts +35 -4
  488. package/src/utils/timers/timers.ts +57 -21
  489. package/build/devtools.d.ts +0 -11
  490. package/build/devtools.d.ts.map +0 -1
  491. package/build/devtools.js +0 -13
  492. package/build/devtools.js.map +0 -1
  493. package/build/internal.d.ts +0 -66
  494. package/build/internal.d.ts.map +0 -1
  495. package/build/internal.js +0 -89
  496. package/build/internal.js.map +0 -1
  497. package/build/services/asgOtaVersionUrl.d.ts +0 -2
  498. package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
  499. package/build/services/asgOtaVersionUrl.js +0 -36
  500. package/build/services/asgOtaVersionUrl.js.map +0 -1
  501. package/src/devtools.ts +0 -13
  502. package/src/internal.ts +0 -158
  503. package/src/services/asgOtaVersionUrl.ts +0 -41
package/README.md CHANGED
@@ -21,7 +21,8 @@ npm install @mentra/engine
21
21
 
22
22
  ## Entry points
23
23
 
24
- The package exposes three entry points (declared in `package.json` `exports`,
24
+ The package exposes its Engine entry points and a supported Bluetooth SDK
25
+ facade (declared in `package.json` `exports`,
25
26
  with the `react-native` condition pointing at `src/` so Metro, tsc and jest
26
27
  resolve live TypeScript source):
27
28
 
@@ -32,15 +33,15 @@ resolve live TypeScript source):
32
33
  OTA policy constants, hardware capability tables, `BgTimer`). Judgment rule:
33
34
  read models, commands, pure functions and types are main; anything that
34
35
  mutates runtime state or exposes a store/service is not.
35
- - **`@mentra/engine/internal`** (`src/internal.ts`) — the migration-era
36
- runtime surface: raw zustand stores (`useCoreStore`, `useSettingsStore`,
37
- `useAppStatusStore`, …) and service singletons (`appRegistry`, `restComms`,
38
- `cloudClientService`, the gallery cluster, the miniapp engine, …). The
39
- host's `@/stores/*` shims re-export from here. New host code should use
40
- `engine.*` instead; `scripts/check-mobile-runtime-boundary.sh` counts every
41
- `/internal` import in `mobile/src` (report-only) as the burn-down metric.
42
- - **`@mentra/engine/devtools`** (`src/devtools.ts`) debug-only singletons
43
- (`miniappRunningRegistry`, `devServerBridge`) for the internal dev screens.
36
+ - **`@mentra/engine/ota`** (`src/react/index.ts`) — shared full-screen OTA
37
+ Native experiences. `MentraLiveOtaFlow` owns the complete check, hotspot or
38
+ Wi-Fi install, APK/MTK/BES progress, reboot, retry, and final verification
39
+ flow so hosts do not implement their own OTA state machines.
40
+ - **`@mentra/engine/bluetooth-sdk`** (`src/bluetooth-sdk/index.ts`) the
41
+ complete public Bluetooth SDK surface, re-exported without a wrapper so it
42
+ has the same singleton identity as `@mentra/bluetooth-sdk`. The supported
43
+ SDK `react`, `types`, `photo-receiver`, and `debug` subpaths are mirrored
44
+ below this path. The SDK's `internal` entrypoint is deliberately not exposed.
44
45
 
45
46
  See `cloud-v2/docs/issues/020-glasses-status-boundary/integration-review.md`
46
47
  §D for the burn-down plan.
@@ -59,21 +60,57 @@ sockets.
59
60
 
60
61
  ```ts
61
62
  import {engine, decideDevLaunchRoute} from "@mentra/engine"
62
- import {webviewBridge, buildMiniappGlobalsScript} from "@mentra/engine/internal"
63
- import {miniappRunningRegistry} from "@mentra/engine/devtools"
63
+ import BluetoothSdk from "@mentra/engine/bluetooth-sdk"
64
64
  ```
65
65
 
66
- - `webviewBridge` — registers per-package WebView message handlers so any
67
- service can `postMessage` JSON into a specific miniapp.
68
- - `miniappRunningRegistry` — session-scoped set of currently-mounted local
69
- miniapp packageNames (foreground + background).
70
- - `buildMiniappGlobalsScript` — builds the `window.MentraOS` injection script
71
- (and CSS variables / console-tap shim) used by every miniapp WebView.
72
66
  - `decideDevLaunchRoute` — pre-flight a dev URL's `miniapp.json` to decide
73
67
  whether to mount live or take the user to the offline screen.
74
68
 
69
+ ### Mentra Live OTA flow
70
+
71
+ Bluetooth-only hosts can render the OTA flow without configuring or starting
72
+ the authenticated cloud/miniapp runtime:
73
+
74
+ ```tsx
75
+ import {MentraLiveOtaFlow} from "@mentra/engine/ota"
76
+ ;<MentraLiveOtaFlow onFinished={() => setShowOta(false)} onOpenWifiSetup={() => setShowWifiSetup(true)} />
77
+ ```
78
+
79
+ The component starts only the glasses-status and OTA projections. A host that
80
+ already called `engine.start()` should pass `initializeRuntime={false}`. Show
81
+ the flow after a Mentra Live connects. Hosts must provide `onOpenWifiSetup`;
82
+ the flow invokes it only for older glasses that cannot provide the OTA hotspot
83
+ transport.
84
+
85
+ Released Engine packages contain a literal immutable OTA manifest URL and
86
+ SHA-256 generated by coordinated release CI. Modern-glasses manifest selection
87
+ is developer override, host-app release pin, then Engine release pin. It does
88
+ not derive a URL from the Bluetooth SDK version or fall through to a
89
+ glasses-reported or mutable production URL. An unpinned source build has OTA
90
+ disabled unless an Expo/React Native host explicitly sets
91
+ `EXPO_PUBLIC_ASG_OTA_VERSION_URL`; native source hosts use the Bluetooth SDK's
92
+ debug `setOtaVersionUrl` surface. Pre-39 glasses retain their separate legacy
93
+ path because those clients ignore the URL sent by the phone.
94
+
75
95
  ## Imports
76
96
 
77
97
  Inside `mobile/modules/engine/src/`, use **relative paths** (`./services/...`,
78
98
  `../utils/...`). The mobile app's `@/*` alias is not configured here — there
79
99
  is no build-time path rewriter for this module.
100
+
101
+ ## Testing
102
+
103
+ Run the suite with `bun run test` (from this directory). It executes
104
+ `scripts/test.sh`, which runs **each test file in its own bun process** — do
105
+ not replace it with a single `bun test src`.
106
+
107
+ Why: bun's `mock.module` patches one process-wide module registry with live
108
+ ESM bindings, last write wins. Several suites mock the same specifiers
109
+ (`"@mentra/bluetooth-sdk/internal"` alone is mocked by `audioTestMocks.ts`,
110
+ `PhonePhotoCoordinator.test.ts`, and others), so in a shared process one
111
+ file's mock clobbers another's and suites that pass alone fail in the
112
+ combined run. Per-file processes give every suite an isolated registry.
113
+
114
+ The same rule applies when writing tests: it is fine to `mock.module` any
115
+ specifier your suite needs, but never rely on a mock installed by a
116
+ _different_ test file — each file must set up everything it imports.
@@ -0,0 +1,2 @@
1
+ export * from "@mentra/bluetooth-sdk/debug";
2
+ //# sourceMappingURL=debug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/bluetooth-sdk/debug.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from "@mentra/bluetooth-sdk/debug";
2
+ //# sourceMappingURL=debug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.js","sourceRoot":"","sources":["../../src/bluetooth-sdk/debug.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA","sourcesContent":["export * from \"@mentra/bluetooth-sdk/debug\"\n"]}
@@ -0,0 +1,3 @@
1
+ export { default } from "@mentra/bluetooth-sdk";
2
+ export * from "@mentra/bluetooth-sdk";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bluetooth-sdk/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,uBAAuB,CAAA;AAC7C,cAAc,uBAAuB,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { default } from "@mentra/bluetooth-sdk";
2
+ export * from "@mentra/bluetooth-sdk";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bluetooth-sdk/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,uBAAuB,CAAA;AAC7C,cAAc,uBAAuB,CAAA","sourcesContent":["export {default} from \"@mentra/bluetooth-sdk\"\nexport * from \"@mentra/bluetooth-sdk\"\n"]}
@@ -0,0 +1,3 @@
1
+ export { default } from "@mentra/bluetooth-sdk/photo-receiver";
2
+ export * from "@mentra/bluetooth-sdk/photo-receiver";
3
+ //# sourceMappingURL=photo-receiver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"photo-receiver.d.ts","sourceRoot":"","sources":["../../src/bluetooth-sdk/photo-receiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,sCAAsC,CAAA;AAC5D,cAAc,sCAAsC,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { default } from "@mentra/bluetooth-sdk/photo-receiver";
2
+ export * from "@mentra/bluetooth-sdk/photo-receiver";
3
+ //# sourceMappingURL=photo-receiver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"photo-receiver.js","sourceRoot":"","sources":["../../src/bluetooth-sdk/photo-receiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,sCAAsC,CAAA;AAC5D,cAAc,sCAAsC,CAAA","sourcesContent":["export {default} from \"@mentra/bluetooth-sdk/photo-receiver\"\nexport * from \"@mentra/bluetooth-sdk/photo-receiver\"\n"]}
@@ -0,0 +1,2 @@
1
+ export * from "@mentra/bluetooth-sdk/react";
2
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/bluetooth-sdk/react.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from "@mentra/bluetooth-sdk/react";
2
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/bluetooth-sdk/react.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA","sourcesContent":["export * from \"@mentra/bluetooth-sdk/react\"\n"]}
@@ -0,0 +1,2 @@
1
+ export * from "@mentra/bluetooth-sdk/types";
2
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/bluetooth-sdk/types.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from "@mentra/bluetooth-sdk/types";
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/bluetooth-sdk/types.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA","sourcesContent":["export * from \"@mentra/bluetooth-sdk/types\"\n"]}
package/build/engine.d.ts CHANGED
@@ -5,13 +5,15 @@
5
5
  * name stays `engine` in code; the public API surface is `engine`.)
6
6
  *
7
7
  * It grows one facade at a time. The migration-era flat store/service exports
8
- * live on the `@mentra/engine/internal` entry (and the debug singletons on
9
- * `@mentra/engine/devtools`); they shrink as screens move onto `engine.*`.
8
+ * remain in a private MentraOS host package; they shrink as screens move onto
9
+ * `engine.*`.
10
10
  */
11
- import { configure } from "./runtime/bootstrap";
11
+ import { configure, updateUiSeams } from "./runtime/bootstrap";
12
12
  export declare const engine: {
13
13
  /** Front door — hand engine auth + config, then start/stop the runtime. */
14
14
  configure: typeof configure;
15
+ /** Merge host-UI seams on a running runtime (scan overlay, wifi setup, …). */
16
+ updateUiSeams: typeof updateUiSeams;
15
17
  /** Start the runtime: mark started + construct/connect the cloud client + begin
16
18
  * syncing device settings to the glasses. */
17
19
  start(): Promise<void>;
@@ -23,7 +25,7 @@ export declare const engine: {
23
25
  connectDefault: () => Promise<void>;
24
26
  disconnect: () => Promise<void>;
25
27
  forget: () => Promise<void>;
26
- connect: (device: import("@mentra/bluetooth-sdk").Device, options?: import("@mentra/bluetooth-sdk").ConnectOptions | undefined) => Promise<void>;
28
+ connect: (device: import("@mentra/bluetooth-sdk").Device, options?: import("@mentra/bluetooth-sdk").ConnectOptions) => Promise<void>;
27
29
  connectSimulated: () => Promise<void>;
28
30
  setDefault: (device: import("@mentra/bluetooth-sdk").Device | null) => Promise<void>;
29
31
  reconnect: () => Promise<boolean>;
@@ -69,14 +71,14 @@ export declare const engine: {
69
71
  restartTranscriber: () => Promise<void>;
70
72
  stt: {
71
73
  currentLanguage: () => string;
72
- languages: () => import("./internal").SttLanguageConfig[];
73
- languageInfo: () => Promise<import("./internal").SttLanguageInfo[]>;
74
- download: (code?: string | undefined, onProgress?: ((progress: import("./internal").SttDownloadProgress) => void) | undefined, onExtractionProgress?: ((progress: import("./internal").SttExtractionProgress) => void) | undefined) => Promise<void>;
74
+ languages: () => import("./services/STTModelManager").LanguageConfig[];
75
+ languageInfo: () => Promise<import("./services/STTModelManager").LanguageInfo[]>;
76
+ download: (code?: string | undefined, onProgress?: ((progress: import("./services/STTModelManager").DownloadProgress) => void) | undefined, onExtractionProgress?: ((progress: import("./services/STTModelManager").ExtractionProgress) => void) | undefined) => Promise<void>;
75
77
  activate: (code: string) => void;
76
78
  cancelDownload: () => Promise<void>;
77
79
  deleteModel: (code?: string | undefined) => Promise<void>;
78
- status: () => import("./internal").OfflineModelDownloadStatus | null;
79
- onStatusChanged: (listener: (status: import("./internal").OfflineModelDownloadStatus | null) => void) => () => void;
80
+ status: () => import("./services/OfflineSpeechModelService").DownloadStatus | null;
81
+ onStatusChanged: (listener: (status: import("./services/OfflineSpeechModelService").DownloadStatus | null) => void) => (() => void);
80
82
  };
81
83
  tts: {
82
84
  currentLanguage: () => string;
@@ -138,15 +140,17 @@ export declare const engine: {
138
140
  };
139
141
  /** Firmware OTA read/observe surface (updateAvailable/status + on* subscriptions). */
140
142
  ota: {
141
- install: (otaVersionUrl?: string | null | undefined) => Promise<import("@mentra/bluetooth-sdk").OtaStartAckEvent>;
143
+ initialize: () => Promise<void>;
144
+ install: (otaVersionUrl?: string | null) => Promise<import("@mentra/bluetooth-sdk").OtaStartAckEvent>;
142
145
  ping: () => Promise<void>;
143
146
  checkForUpdates: (options?: import(".").OtaCheckCurrentGlassesOptions) => Promise<import(".").OtaCheckCurrentGlassesResult>;
144
147
  clearUpdateAvailable: () => void;
145
148
  clearProgress: () => void;
146
- replacePendingUpdateSequence: (updates: import("@mentra/bluetooth-sdk/internal").OtaUpdateInfo["updates"]) => import("@mentra/bluetooth-sdk/internal").OtaUpdateInfo | null;
149
+ replacePendingUpdateSequence: (updates: import("@mentra/bluetooth-sdk").OtaUpdateInfo["updates"]) => import("@mentra/bluetooth-sdk").OtaUpdateInfo | null;
147
150
  clearBuildNumberForNextCheck: () => void;
148
151
  markMtkUpdatedThisSession: (updated: boolean) => void;
149
152
  installSession: {
153
+ prepare: (result: import(".").OtaCheckCurrentGlassesResult) => "wifi" | "hotspot";
150
154
  attach: () => void;
151
155
  detach: () => void;
152
156
  retry: () => void;
@@ -155,10 +159,10 @@ export declare const engine: {
155
159
  snapshot: () => import(".").OtaInstallSnapshot;
156
160
  onSnapshot: (cb: (snapshot: import(".").OtaInstallSnapshot) => void) => (() => void);
157
161
  };
158
- updateAvailable: () => import("@mentra/bluetooth-sdk/internal").OtaUpdateInfo | null;
162
+ updateAvailable: () => import("@mentra/bluetooth-sdk").OtaUpdateInfo | null;
159
163
  status: () => import("@mentra/bluetooth-sdk").OtaStatus | null;
160
164
  snapshot: () => import(".").OtaSnapshot;
161
- onUpdateAvailable: (cb: (info: import("@mentra/bluetooth-sdk/internal").OtaUpdateInfo | null) => void) => (() => void);
165
+ onUpdateAvailable: (cb: (info: import("@mentra/bluetooth-sdk").OtaUpdateInfo | null) => void) => (() => void);
162
166
  onStatus: (cb: (status: import("@mentra/bluetooth-sdk").OtaStatus | null) => void) => (() => void);
163
167
  onSnapshot: (cb: (snapshot: import(".").OtaSnapshot) => void) => (() => void);
164
168
  };
@@ -178,6 +182,8 @@ export declare const engine: {
178
182
  miniapps: {
179
183
  list: () => import("./types").ClientApp[];
180
184
  onChanged: (cb: (apps: import("./types").ClientApp[]) => void) => (() => void);
185
+ buttonPressSubscribers: () => string[];
186
+ onButtonPressSubscribersChanged: (cb: (packageNames: string[]) => void) => (() => void);
181
187
  refresh: () => Promise<void>;
182
188
  start: (app: import("./types").ClientApp, opts?: import(".").StartOptions | undefined) => Promise<boolean>;
183
189
  stop: (packageName: string) => Promise<void>;
@@ -210,9 +216,13 @@ export declare const engine: {
210
216
  model: import("@mentra/bluetooth-sdk").DeviceModel;
211
217
  name: string;
212
218
  address?: string;
219
+ projectName?: string;
213
220
  rssi?: number;
221
+ pairingMode?: boolean;
222
+ pairingCode?: string;
223
+ securePairingCapable?: boolean;
214
224
  }[];
215
- onFound: (cb: (results: ReturnType<() => import("./stores/core").CoreState>["searchResults"]) => void) => (() => void);
225
+ onFound: (cb: (results: import("@mentra/bluetooth-sdk").Device[]) => void) => (() => void);
216
226
  pair: (device: import("@mentra/bluetooth-sdk").Device, options?: import("@mentra/bluetooth-sdk").ConnectOptions) => Promise<void>;
217
227
  setDefault: (device: import("@mentra/bluetooth-sdk").Device | null) => Promise<void>;
218
228
  setBluetoothClassicTarget: (device: import("@mentra/bluetooth-sdk").Device) => Promise<void>;
@@ -224,8 +234,6 @@ export declare const engine: {
224
234
  };
225
235
  /** Phone→glasses notification forwarding (Android). */
226
236
  phoneNotifications: {
227
- enabled: () => boolean;
228
- setEnabled: (enabled: boolean) => import("typesafe-ts").AsyncResult<void, Error> | undefined;
229
237
  installedApps: () => Promise<Array<{
230
238
  packageName: string;
231
239
  appName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAC,SAAS,EAAiD,MAAM,qBAAqB,CAAA;AAkC7F,eAAO,MAAM,MAAM;IACjB,2EAA2E;;IAE3E;iDAC6C;;IAyE7C;;yCAEqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA0BrC,mFAAmF;;;;;;;;IAEnF,sEAAsE;;;;;;;;;;;;IAEtE,qFAAqF;;;gBAxFtE,CAAC;mBACd,CAAH;;;gBAIe,CAAC;mBAAiB,CAAC;;;;;;;;;;;;;;;;IAqFjC,qEAAqE;;;;IAErE,sFAAsF;;;;;;;;;;;;;;;;;;;;;;;;;;IAEtF,6EAA6E;;;;;;;;;;;;IAE7E,iFAAiF;;;;;;;;;;;;;;;;;IAEjF,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAE9C,uDAAuD;;;;;;;;;;;;;;IAEvD,8EAA8E;;;;;;;IAE9E,qFAAqF;;;;;;;;;;;;;;CAGtF,CAAA"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAC,SAAS,EAAkD,aAAa,EAAC,MAAM,qBAAqB,CAAA;AAmC5G,eAAO,MAAM,MAAM;IACjB,2EAA2E;;IAE3E,8EAA8E;;IAE9E;iDAC6C;;IA0E7C;;yCAEqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2BrC,mFAAmF;;;;;;;;IAEnF,sEAAsE;;;;;;;;;;;;IAEtE,qFAAqF;;;gBA7FlC,CAAC;mBAAiB,CAAC;;;gBAKhD,CAAC;mBAAiB,CAAC;;;;;;;;;;;;;;;;IA0FzC,qEAAqE;;;;IAErE,sFAAsF;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEtF,6EAA6E;;;;;;;;;;;;IAE7E,iFAAiF;;;;;;;;;;;;;;;;;;;IAEjF,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAE9C,uDAAuD;;;;;;;;;;;;IAEvD,8EAA8E;;;;;;;IAE9E,qFAAqF;;;;;;;;;;;;;;CAGtF,CAAA"}
package/build/engine.js CHANGED
@@ -5,16 +5,17 @@
5
5
  * name stays `engine` in code; the public API surface is `engine`.)
6
6
  *
7
7
  * It grows one facade at a time. The migration-era flat store/service exports
8
- * live on the `@mentra/engine/internal` entry (and the debug singletons on
9
- * `@mentra/engine/devtools`); they shrink as screens move onto `engine.*`.
8
+ * remain in a private MentraOS host package; they shrink as screens move onto
9
+ * `engine.*`.
10
10
  */
11
- import { configure, start as bootstrapStart, stop as bootstrapStop } from "./runtime/bootstrap";
11
+ import { configure, start as bootstrapStart, stop as bootstrapStop, updateUiSeams } from "./runtime/bootstrap";
12
12
  import { cloudClientService } from "./services/CloudClientService";
13
13
  import { hydrateDeviceStore, demoteOrphanedDefaultWearable } from "./services/DeviceStoreHydration";
14
14
  import { startGlassesSettingsSync, stopGlassesSettingsSync } from "./services/GlassesSettingsSync";
15
15
  import { startGlassesStatusProjection, stopGlassesStatusProjection } from "./services/GlassesStatusProjection";
16
16
  import { startOtaService, stopOtaService } from "./services/OtaService";
17
17
  import { startAudioCloudUplink, stopAudioCloudUplink } from "./services/AudioCloudUplink";
18
+ import { startSupportProfileSync, stopSupportProfileSync } from "./services/SupportProfileSync";
18
19
  import { startDeviceEventRouter, stopDeviceEventRouter } from "./services/DeviceEventRouter";
19
20
  import { startPhoneNotificationsSync, stopPhoneNotificationsSync } from "./services/PhoneNotificationsSync";
20
21
  import { startCaptionsTesterReportService, stopCaptionsTesterReportService } from "./services/CaptionsTesterReportService";
@@ -41,6 +42,8 @@ import { logBuffer } from "./utils/devLogging";
41
42
  export const engine = {
42
43
  /** Front door — hand engine auth + config, then start/stop the runtime. */
43
44
  configure,
45
+ /** Merge host-UI seams on a running runtime (scan overlay, wifi setup, …). */
46
+ updateUiSeams,
44
47
  /** Start the runtime: mark started + construct/connect the cloud client + begin
45
48
  * syncing device settings to the glasses. */
46
49
  async start() {
@@ -55,7 +58,7 @@ export const engine = {
55
58
  // Project native device status -> the engine stores (the inbound feed the rest
56
59
  // of the runtime reads). Established first so the stores are live before the
57
60
  // syncs below react to them.
58
- startGlassesStatusProjection();
61
+ startGlassesStatusProjection((changed) => localMiniappRuntime.forwardEvent("glasses_connection_state", changed));
59
62
  // Route the rest of the inbound device events (wifi/hotspot/gallery -> stores+bus,
60
63
  // photo/stream -> coordinators, button/touch/accel/head -> miniapps, save_setting ->
61
64
  // store, miniapp_selected -> launcher) so a bare OEM gets device data, not just the
@@ -91,6 +94,7 @@ export const engine = {
91
94
  catch (error) {
92
95
  console.warn("engine.start: initial Cloud V2 core token sync failed:", error instanceof Error ? error.message : error);
93
96
  }
97
+ startSupportProfileSync();
94
98
  // Push device-setting changes to the glasses for ANY host, so
95
99
  // engine.glasses.settings.set() reaches the device (not just the Mentra app).
96
100
  startGlassesSettingsSync();
@@ -131,6 +135,7 @@ export const engine = {
131
135
  await safely("device event router", stopDeviceEventRouter);
132
136
  await safely("ota service", stopOtaService);
133
137
  await safely("audio cloud uplink", stopAudioCloudUplink);
138
+ await safely("support profile sync", stopSupportProfileSync);
134
139
  await safely("phone notifications sync", stopPhoneNotificationsSync);
135
140
  await safely("captions tester report service", stopCaptionsTesterReportService);
136
141
  await safely("mentrajs crashloop report service", stopMentraJSCrashloopReportService);
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `engine` — the namespaced OEM-facing engine API (the \"(A) host API\" from the\n * Phase-1 contract). Host UI calls `engine.<domain>.<method>()`; each domain is a\n * typed facade over the runtime. (Exported from the `@mentra/engine` module, whose\n * name stays `engine` in code; the public API surface is `engine`.)\n *\n * It grows one facade at a time. The migration-era flat store/service exports\n * live on the `@mentra/engine/internal` entry (and the debug singletons on\n * `@mentra/engine/devtools`); they shrink as screens move onto `engine.*`.\n */\nimport {configure, start as bootstrapStart, stop as bootstrapStop} from \"./runtime/bootstrap\"\nimport {cloudClientService} from \"./services/CloudClientService\"\nimport {hydrateDeviceStore, demoteOrphanedDefaultWearable} from \"./services/DeviceStoreHydration\"\nimport {startGlassesSettingsSync, stopGlassesSettingsSync} from \"./services/GlassesSettingsSync\"\nimport {startGlassesStatusProjection, stopGlassesStatusProjection} from \"./services/GlassesStatusProjection\"\nimport {startOtaService, stopOtaService} from \"./services/OtaService\"\nimport {startAudioCloudUplink, stopAudioCloudUplink} from \"./services/AudioCloudUplink\"\nimport {startDeviceEventRouter, stopDeviceEventRouter} from \"./services/DeviceEventRouter\"\nimport {startPhoneNotificationsSync, stopPhoneNotificationsSync} from \"./services/PhoneNotificationsSync\"\nimport {startCaptionsTesterReportService, stopCaptionsTesterReportService} from \"./services/CaptionsTesterReportService\"\nimport {\n startMentraJSCrashloopReportService,\n stopMentraJSCrashloopReportService,\n} from \"./services/MentraJSCrashloopReportService\"\nimport {ensureMiniappEngine, stopMiniappEngine} from \"./services/MiniappEngine\"\nimport localMiniappRuntime from \"./services/LocalMiniappRuntime\"\nimport displayProcessor from \"./services/DisplayProcessor\"\nimport {gallerySyncService} from \"./services/asg/gallerySyncService\"\nimport {glasses} from \"./facades/glasses\"\nimport {display} from \"./facades/display\"\nimport {speech} from \"./facades/speech\"\nimport {session} from \"./facades/session\"\nimport {settings} from \"./facades/settings\"\nimport {dev} from \"./facades/dev\"\nimport {reports} from \"./facades/reports\"\nimport {ota} from \"./facades/ota\"\nimport {gallery} from \"./facades/gallery\"\nimport {miniapps} from \"./facades/miniapps\"\nimport {pairing} from \"./facades/pairing\"\nimport {phoneNotifications} from \"./facades/phoneNotifications\"\nimport {permissions} from \"./facades/permissions\"\nimport {notifications} from \"./facades/notifications\"\nimport {logBuffer} from \"./utils/devLogging\"\n\nexport const engine = {\n /** Front door — hand engine auth + config, then start/stop the runtime. */\n configure,\n /** Start the runtime: mark started + construct/connect the cloud client + begin\n * syncing device settings to the glasses. */\n async start() {\n // Reports attach recent phone logs, so engine owns console interception for\n // OEM hosts too. Idempotent; the Mentra host may start it earlier.\n logBuffer.startConsoleInterception()\n await bootstrapStart()\n // Construct + connect the cloud client so the documented configure()+start()\n // lifecycle yields a live engine.session for OEMs. Idempotent for repeated\n // start() calls.\n cloudClientService.init()\n // Project native device status -> the engine stores (the inbound feed the rest\n // of the runtime reads). Established first so the stores are live before the\n // syncs below react to them.\n startGlassesStatusProjection()\n // Route the rest of the inbound device events (wifi/hotspot/gallery -> stores+bus,\n // photo/stream -> coordinators, button/touch/accel/head -> miniapps, save_setting ->\n // store, miniapp_selected -> launcher) so a bare OEM gets device data, not just the\n // Mentra app's MantleManager.\n startDeviceEventRouter()\n // Hydration contract: the native DeviceStore is in-memory and starts empty\n // every launch; seed it from the persisted settings BEFORE start() resolves\n // so every post-start getDefaultDevice() read is a trustworthy two-state\n // answer (no false \"absent\" for genuinely-paired users at cold start).\n // Ordered before startGlassesSettingsSync so the settings load can't\n // double-push through the change subscription. A failed hydration must not\n // brick the runtime: start() continues, and the guards that consume\n // hasDefaultDevice() see the rejection and fail open.\n try {\n await hydrateDeviceStore()\n // Boot repair: a persisted default_wearable without a native default\n // device (identity abandoned mid-pairing, or resurrected from the server\n // before identity stopped syncing) demotes to pending_wearable so hosts\n // render finish-pairing instead of a connect that would throw.\n await demoteOrphanedDefaultWearable()\n } catch (error) {\n console.warn(\"engine.start: device-store hydration failed:\", error instanceof Error ? error.message : error)\n }\n // Project the glasses' OTA events into the store for the engine.ota read surface.\n startOtaService()\n // Forward glasses mic_lc3 frames to the v2 cloud session so cloud transcription\n // works for any host (not just the Mentra app's host-side MantleManager fork).\n startAudioCloudUplink()\n try {\n await cloudClientService.syncCoreTokenToBluetooth()\n } catch (error) {\n console.warn(\n \"engine.start: initial Cloud V2 core token sync failed:\",\n error instanceof Error ? error.message : error,\n )\n }\n // Push device-setting changes to the glasses for ANY host, so\n // engine.glasses.settings.set() reaches the device (not just the Mentra app).\n startGlassesSettingsSync()\n // Same for phone-notification config -> the native listener (Android).\n startPhoneNotificationsSync()\n // Android internal/e2e: laptop captions tester can broadcast a failure intent;\n // engine owns turning that into a Cloud V2 report.\n startCaptionsTesterReportService()\n // MentraJS crashloop-disabled is runtime state; engine owns filing the\n // automatic report while hosts only render alert/telemetry side effects.\n startMentraJSCrashloopReportService()\n // Bring up the local-miniapp engine so a bare OEM can run MentraJS miniapps:\n // the LocalMiniappRuntime (registry + WebView bridge), the MentraJS router\n // (crust-bound spawn/dispatch pump + launcher wiring), the DisplayProcessor\n // (layout arbitration over the engine stores), and the gallery-sync service.\n // All idempotent — when the Mentra app's host bootstrap also calls these, the\n // second call is a no-op. Host-only crashloop telemetry is attached\n // separately by the Mentra app.\n localMiniappRuntime.initialize()\n ensureMiniappEngine()\n displayProcessor.attachToRuntime()\n gallerySyncService.initialize()\n },\n /** Stop the runtime: tear down the settings sync + cloud client + mark stopped.\n * Each step is guarded so one failing teardown can't skip the rest and leak\n * the remaining runtime services. */\n async stop() {\n const safely = async (label: string, step: () => unknown): Promise<void> => {\n try {\n await step()\n } catch (error) {\n console.warn(`engine.stop: ${label} failed:`, error)\n }\n }\n await safely(\"glasses settings sync\", stopGlassesSettingsSync)\n await safely(\"glasses status projection\", stopGlassesStatusProjection)\n await safely(\"device event router\", stopDeviceEventRouter)\n await safely(\"ota service\", stopOtaService)\n await safely(\"audio cloud uplink\", stopAudioCloudUplink)\n await safely(\"phone notifications sync\", stopPhoneNotificationsSync)\n await safely(\"captions tester report service\", stopCaptionsTesterReportService)\n await safely(\"mentrajs crashloop report service\", stopMentraJSCrashloopReportService)\n await safely(\"miniapp engine\", stopMiniappEngine)\n await safely(\"local miniapp runtime\", () => localMiniappRuntime.cleanup())\n await safely(\"display processor\", () => displayProcessor.detachFromRuntime())\n await safely(\"gallery sync service\", () => gallerySyncService.cleanup())\n await safely(\"cloud client\", () => cloudClientService.stop())\n await safely(\"bootstrap\", bootstrapStop)\n },\n glasses,\n speech,\n /** Cloud (cloud-v2) live-session status + account ops — engine owns the client. */\n session,\n /** Typed keyed user settings over the engine-owned settings store. */\n settings,\n /** Developer/debug surface (backend+cloud URL overrides, reconnect, min version). */\n dev,\n /** Bug-report, automatic runtime report, and feedback submission. */\n reports,\n /** Firmware OTA read/observe surface (updateAvailable/status + on* subscriptions). */\n ota,\n /** Gallery sync: status/onStatus · onNotice (host renders) · sync/cancel. */\n gallery,\n /** Miniapp lifecycle (the WebView bridge primitives are exported separately). */\n miniapps,\n /** First-time glasses discovery + pairing. */\n pairing,\n /** Phone→glasses notification forwarding (Android). */\n phoneNotifications,\n /** OS permissions (check/request/openSettings + per-miniapp requirements). */\n permissions,\n /** Inbound alerts engine→host (crashloop, version-incompatible, connection loss). */\n notifications,\n display,\n}\n"]}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `engine` — the namespaced OEM-facing engine API (the \"(A) host API\" from the\n * Phase-1 contract). Host UI calls `engine.<domain>.<method>()`; each domain is a\n * typed facade over the runtime. (Exported from the `@mentra/engine` module, whose\n * name stays `engine` in code; the public API surface is `engine`.)\n *\n * It grows one facade at a time. The migration-era flat store/service exports\n * remain in a private MentraOS host package; they shrink as screens move onto\n * `engine.*`.\n */\nimport {configure, start as bootstrapStart, stop as bootstrapStop, updateUiSeams} from \"./runtime/bootstrap\"\nimport {cloudClientService} from \"./services/CloudClientService\"\nimport {hydrateDeviceStore, demoteOrphanedDefaultWearable} from \"./services/DeviceStoreHydration\"\nimport {startGlassesSettingsSync, stopGlassesSettingsSync} from \"./services/GlassesSettingsSync\"\nimport {startGlassesStatusProjection, stopGlassesStatusProjection} from \"./services/GlassesStatusProjection\"\nimport {startOtaService, stopOtaService} from \"./services/OtaService\"\nimport {startAudioCloudUplink, stopAudioCloudUplink} from \"./services/AudioCloudUplink\"\nimport {startSupportProfileSync, stopSupportProfileSync} from \"./services/SupportProfileSync\"\nimport {startDeviceEventRouter, stopDeviceEventRouter} from \"./services/DeviceEventRouter\"\nimport {startPhoneNotificationsSync, stopPhoneNotificationsSync} from \"./services/PhoneNotificationsSync\"\nimport {startCaptionsTesterReportService, stopCaptionsTesterReportService} from \"./services/CaptionsTesterReportService\"\nimport {\n startMentraJSCrashloopReportService,\n stopMentraJSCrashloopReportService,\n} from \"./services/MentraJSCrashloopReportService\"\nimport {ensureMiniappEngine, stopMiniappEngine} from \"./services/MiniappEngine\"\nimport localMiniappRuntime from \"./services/LocalMiniappRuntime\"\nimport displayProcessor from \"./services/DisplayProcessor\"\nimport {gallerySyncService} from \"./services/asg/gallerySyncService\"\nimport {glasses} from \"./facades/glasses\"\nimport {display} from \"./facades/display\"\nimport {speech} from \"./facades/speech\"\nimport {session} from \"./facades/session\"\nimport {settings} from \"./facades/settings\"\nimport {dev} from \"./facades/dev\"\nimport {reports} from \"./facades/reports\"\nimport {ota} from \"./facades/ota\"\nimport {gallery} from \"./facades/gallery\"\nimport {miniapps} from \"./facades/miniapps\"\nimport {pairing} from \"./facades/pairing\"\nimport {phoneNotifications} from \"./facades/phoneNotifications\"\nimport {permissions} from \"./facades/permissions\"\nimport {notifications} from \"./facades/notifications\"\nimport {logBuffer} from \"./utils/devLogging\"\n\nexport const engine = {\n /** Front door — hand engine auth + config, then start/stop the runtime. */\n configure,\n /** Merge host-UI seams on a running runtime (scan overlay, wifi setup, …). */\n updateUiSeams,\n /** Start the runtime: mark started + construct/connect the cloud client + begin\n * syncing device settings to the glasses. */\n async start() {\n // Reports attach recent phone logs, so engine owns console interception for\n // OEM hosts too. Idempotent; the Mentra host may start it earlier.\n logBuffer.startConsoleInterception()\n await bootstrapStart()\n // Construct + connect the cloud client so the documented configure()+start()\n // lifecycle yields a live engine.session for OEMs. Idempotent for repeated\n // start() calls.\n cloudClientService.init()\n // Project native device status -> the engine stores (the inbound feed the rest\n // of the runtime reads). Established first so the stores are live before the\n // syncs below react to them.\n startGlassesStatusProjection((changed) => localMiniappRuntime.forwardEvent(\"glasses_connection_state\", changed))\n // Route the rest of the inbound device events (wifi/hotspot/gallery -> stores+bus,\n // photo/stream -> coordinators, button/touch/accel/head -> miniapps, save_setting ->\n // store, miniapp_selected -> launcher) so a bare OEM gets device data, not just the\n // Mentra app's MantleManager.\n startDeviceEventRouter()\n // Hydration contract: the native DeviceStore is in-memory and starts empty\n // every launch; seed it from the persisted settings BEFORE start() resolves\n // so every post-start getDefaultDevice() read is a trustworthy two-state\n // answer (no false \"absent\" for genuinely-paired users at cold start).\n // Ordered before startGlassesSettingsSync so the settings load can't\n // double-push through the change subscription. A failed hydration must not\n // brick the runtime: start() continues, and the guards that consume\n // hasDefaultDevice() see the rejection and fail open.\n try {\n await hydrateDeviceStore()\n // Boot repair: a persisted default_wearable without a native default\n // device (identity abandoned mid-pairing, or resurrected from the server\n // before identity stopped syncing) demotes to pending_wearable so hosts\n // render finish-pairing instead of a connect that would throw.\n await demoteOrphanedDefaultWearable()\n } catch (error) {\n console.warn(\"engine.start: device-store hydration failed:\", error instanceof Error ? error.message : error)\n }\n // Project the glasses' OTA events into the store for the engine.ota read surface.\n startOtaService()\n // Forward glasses mic_lc3 frames to the v2 cloud session so cloud transcription\n // works for any host (not just the Mentra app's host-side MantleManager fork).\n startAudioCloudUplink()\n try {\n await cloudClientService.syncCoreTokenToBluetooth()\n } catch (error) {\n console.warn(\n \"engine.start: initial Cloud V2 core token sync failed:\",\n error instanceof Error ? error.message : error,\n )\n }\n startSupportProfileSync()\n // Push device-setting changes to the glasses for ANY host, so\n // engine.glasses.settings.set() reaches the device (not just the Mentra app).\n startGlassesSettingsSync()\n // Same for phone-notification config -> the native listener (Android).\n startPhoneNotificationsSync()\n // Android internal/e2e: laptop captions tester can broadcast a failure intent;\n // engine owns turning that into a Cloud V2 report.\n startCaptionsTesterReportService()\n // MentraJS crashloop-disabled is runtime state; engine owns filing the\n // automatic report while hosts only render alert/telemetry side effects.\n startMentraJSCrashloopReportService()\n // Bring up the local-miniapp engine so a bare OEM can run MentraJS miniapps:\n // the LocalMiniappRuntime (registry + WebView bridge), the MentraJS router\n // (crust-bound spawn/dispatch pump + launcher wiring), the DisplayProcessor\n // (layout arbitration over the engine stores), and the gallery-sync service.\n // All idempotent — when the Mentra app's host bootstrap also calls these, the\n // second call is a no-op. Host-only crashloop telemetry is attached\n // separately by the Mentra app.\n localMiniappRuntime.initialize()\n ensureMiniappEngine()\n displayProcessor.attachToRuntime()\n gallerySyncService.initialize()\n },\n /** Stop the runtime: tear down the settings sync + cloud client + mark stopped.\n * Each step is guarded so one failing teardown can't skip the rest and leak\n * the remaining runtime services. */\n async stop() {\n const safely = async (label: string, step: () => unknown): Promise<void> => {\n try {\n await step()\n } catch (error) {\n console.warn(`engine.stop: ${label} failed:`, error)\n }\n }\n await safely(\"glasses settings sync\", stopGlassesSettingsSync)\n await safely(\"glasses status projection\", stopGlassesStatusProjection)\n await safely(\"device event router\", stopDeviceEventRouter)\n await safely(\"ota service\", stopOtaService)\n await safely(\"audio cloud uplink\", stopAudioCloudUplink)\n await safely(\"support profile sync\", stopSupportProfileSync)\n await safely(\"phone notifications sync\", stopPhoneNotificationsSync)\n await safely(\"captions tester report service\", stopCaptionsTesterReportService)\n await safely(\"mentrajs crashloop report service\", stopMentraJSCrashloopReportService)\n await safely(\"miniapp engine\", stopMiniappEngine)\n await safely(\"local miniapp runtime\", () => localMiniappRuntime.cleanup())\n await safely(\"display processor\", () => displayProcessor.detachFromRuntime())\n await safely(\"gallery sync service\", () => gallerySyncService.cleanup())\n await safely(\"cloud client\", () => cloudClientService.stop())\n await safely(\"bootstrap\", bootstrapStop)\n },\n glasses,\n speech,\n /** Cloud (cloud-v2) live-session status + account ops — engine owns the client. */\n session,\n /** Typed keyed user settings over the engine-owned settings store. */\n settings,\n /** Developer/debug surface (backend+cloud URL overrides, reconnect, min version). */\n dev,\n /** Bug-report, automatic runtime report, and feedback submission. */\n reports,\n /** Firmware OTA read/observe surface (updateAvailable/status + on* subscriptions). */\n ota,\n /** Gallery sync: status/onStatus · onNotice (host renders) · sync/cancel. */\n gallery,\n /** Miniapp lifecycle (the WebView bridge primitives are exported separately). */\n miniapps,\n /** First-time glasses discovery + pairing. */\n pairing,\n /** Phone→glasses notification forwarding (Android). */\n phoneNotifications,\n /** OS permissions (check/request/openSettings + per-miniapp requirements). */\n permissions,\n /** Inbound alerts engine→host (crashloop, version-incompatible, connection loss). */\n notifications,\n display,\n}\n"]}
@@ -34,8 +34,9 @@ export declare const dev: {
34
34
  /**
35
35
  * Side-load a miniapp being served from a dev machine (the `mentra dev` / CLI
36
36
  * flow) by its URL: probes `<url>/miniapp.json`, and on a reachable manifest
37
- * registers it into the single dev slot so it appears in `engine.miniapps`
38
- * and can be started. This is the OEM-host equivalent of the first-party
37
+ * registers it under its manifest package so it appears in `engine.miniapps`
38
+ * and can coexist with other dev miniapps. This is the OEM-host equivalent
39
+ * of the first-party
39
40
  * developer-URL screen — the registration itself is engine-internal, so a
40
41
  * host reaches it here rather than the internal registry. Rendering still
41
42
  * flows through the normal display path once the miniapp is started.
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/facades/dev.ts"],"names":[],"mappings":"AA+DA,iBAAS,oBAAoB;;;;;;;;;;;EAkB5B;AAED,MAAM,MAAM,wBAAwB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAE9E,eAAO,MAAM,GAAG;IACd,+CAA+C;qBAChC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAC;IAIhD,0EAA0E;yBACrD;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAC;IAkBtD,8EAA8E;0BAC1D,IAAI;IAExB,iFAAiF;uBAChE,MAAM;IACvB;;;OAGG;2BACkB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAK5C;;;;;;;;OAQG;0BAEI,MAAM,SACJ,MAAM,KACZ,OAAO,CAAC;QAAC,EAAE,EAAE,IAAI,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,GAAG;QAAC,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC;IAqCtF,qEAAqE;yBAClD,wBAAwB;IAE3C,gFAAgF;0BAC1D,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC;CAmBhF,CAAA"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/facades/dev.ts"],"names":[],"mappings":"AA+DA,iBAAS,oBAAoB;;;;;;;;;;;EAkB5B;AAED,MAAM,MAAM,wBAAwB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAE9E,eAAO,MAAM,GAAG;IACd,+CAA+C;qBAChC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAC;IAIhD,0EAA0E;yBACrD;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAC;IAkBtD,8EAA8E;0BAC1D,IAAI;IAExB,iFAAiF;uBAChE,MAAM;IACvB;;;OAGG;2BACkB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAK5C;;;;;;;;;OASG;0BAEI,MAAM,SACJ,MAAM,KACZ,OAAO,CAAC;QAAC,EAAE,EAAE,IAAI,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,GAAG;QAAC,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC;IAyCtF,qEAAqE;yBAClD,wBAAwB;IAE3C,gFAAgF;0BAC1D,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC;CAmBhF,CAAA"}
@@ -116,8 +116,9 @@ export const dev = {
116
116
  /**
117
117
  * Side-load a miniapp being served from a dev machine (the `mentra dev` / CLI
118
118
  * flow) by its URL: probes `<url>/miniapp.json`, and on a reachable manifest
119
- * registers it into the single dev slot so it appears in `engine.miniapps`
120
- * and can be started. This is the OEM-host equivalent of the first-party
119
+ * registers it under its manifest package so it appears in `engine.miniapps`
120
+ * and can coexist with other dev miniapps. This is the OEM-host equivalent
121
+ * of the first-party
121
122
  * developer-URL screen — the registration itself is engine-internal, so a
122
123
  * host reaches it here rather than the internal registry. Rendering still
123
124
  * flows through the normal display path once the miniapp is started.
@@ -131,26 +132,31 @@ export const dev = {
131
132
  return { ok: false, error: "dev server unreachable, or no miniapp.json served there" };
132
133
  }
133
134
  const manifest = result.manifest;
135
+ const appName = name ?? manifest.name ?? "Dev Miniapp";
136
+ const packageName = manifest.packageName ?? DEV_APP_PACKAGE_NAME;
137
+ // Persist the host that answered — not the stale input IP — so home-tile
138
+ // relaunches skip a dead LAN address after mDNS/Metro failover.
139
+ const resolvedUrl = result.resolvedUrl || devUrl;
134
140
  // The `mentra-miniapp dev` server puts the hot-reload/log sidecar on the
135
141
  // user port PLUS ONE — same convention as the first-party developer-URL
136
142
  // screen's deriveDevPort.
137
143
  let devPort;
138
144
  try {
139
- const parsed = Number(new URL(devUrl).port);
145
+ const parsed = Number(new URL(resolvedUrl).port);
140
146
  devPort = Number.isFinite(parsed) && parsed > 0 ? parsed + 1 : undefined;
141
147
  }
142
148
  catch {
143
149
  devPort = undefined;
144
150
  }
145
- const appName = name ?? manifest.name ?? "Dev Miniapp";
146
- registerDevApp({
147
- // The REAL manifest package: registerDevApp preserves it as
148
- // sourcePackageName (miniapp auth + dev-slot cleanup key off it) before
149
- // forcing packageName to the single dev slot.
150
- packageName: manifest.packageName ?? DEV_APP_PACKAGE_NAME,
151
+ const existing = useAppStatusStore.getState().apps.find((app) => app.packageName === packageName);
152
+ if (existing?.running)
153
+ await useAppStatusStore.getState().stop(packageName);
154
+ await registerDevApp({
155
+ packageName,
151
156
  name: appName,
152
- iconUrl: manifest.icon ? new URL(manifest.icon, `${devUrl}/`).toString() : `${devUrl}/icon.png`,
153
- devUrl,
157
+ iconUrl: manifest.icon ? new URL(manifest.icon, `${resolvedUrl}/`).toString() : `${resolvedUrl}/icon.png`,
158
+ // Persist the host that answered — not the stale input IP.
159
+ devUrl: resolvedUrl,
154
160
  devPort,
155
161
  type: manifest.type,
156
162
  permissions: manifest.permissions,
@@ -158,7 +164,7 @@ export const dev = {
158
164
  actions: manifest.actions,
159
165
  });
160
166
  await useAppStatusStore.getState().refresh();
161
- return { ok: true, packageName: DEV_APP_PACKAGE_NAME, name: appName };
167
+ return { ok: true, packageName, name: appName };
162
168
  },
163
169
  /** Current engine runtime status for engine-owned debug surfaces. */
164
170
  runtimeStatus: () => projectRuntimeStatus(),
@@ -1 +1 @@
1
- {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/facades/dev.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dev facade — `engine.dev`: developer/debug surface over engine-owned state.\n * Backend/cloud URL overrides read+write the engine settings store; the cloud\n * URL setters reconnect the engine-owned cloud client onto the new endpoints;\n *\n * NOTE: the dev-time endpoint *resolution* (Metro-host auto-detect, env defaults)\n * still lives host-side in `@/services/cloudClient` during the migration; this\n * facade manages the explicit overrides + reconnect.\n */\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport {isGlassesReady} from \"../services/GlassesReadiness\"\nimport {useCloudClientStatusStore} from \"../stores/cloudClientStatus\"\nimport {useConnectionStore} from \"../stores/connection\"\nimport {useCoreStore} from \"../stores/core\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {useSettingsStore, SETTINGS} from \"../stores/settings\"\nimport {cloudClientService} from \"../services/CloudClientService\"\nimport {getConfigValues} from \"../runtime/bootstrap\"\nimport {decideDevLaunchRoute} from \"../utils/devMiniappLaunch\"\nimport {registerDevApp, DEV_APP_PACKAGE_NAME, type DevAppRecord} from \"../services/AppRegistry\"\nimport {useAppStatusStore} from \"../stores/apps\"\n\ntype CloudUrlOverrides = {core?: string; runtime?: string}\n\n/**\n * Reconnect the cloud client onto the current cloud-URL overrides. Explicit\n * partial overrides merge over the boot-resolved config (which carries the\n * host's Metro/env URL resolution); both empty clears the live override.\n */\nfunction applyCloudUrlReconnect(urls: CloudUrlOverrides = currentCloudUrlOverrides()): void {\n const resolved = resolveCloudUrlReconnectTarget(urls)\n if (resolved === undefined) {\n cloudClientService.reconnect(null)\n } else if (resolved) {\n cloudClientService.reconnect(resolved)\n } else {\n console.warn(\"engine.dev.setCloudUrls: partial cloud override missing boot-resolved sibling endpoint\")\n }\n}\n\nfunction currentCloudUrlOverrides(): CloudUrlOverrides {\n const s = useSettingsStore.getState()\n return {\n core: trimSetting(s.getSetting(SETTINGS.cloud_core_url.key)),\n runtime: trimSetting(s.getSetting(SETTINGS.cloud_runtime_url.key)),\n }\n}\n\nfunction resolveCloudUrlReconnectTarget(urls: CloudUrlOverrides): {core: string; runtime: string} | null | undefined {\n const core = trimSetting(urls.core)\n const runtime = trimSetting(urls.runtime)\n if (!core && !runtime) return undefined\n\n const config = getConfigValues()\n const resolvedCore = core || config.coreUrl?.trim()\n const resolvedRuntime = runtime || config.runtimeUrl?.trim()\n return resolvedCore && resolvedRuntime ? {core: resolvedCore, runtime: resolvedRuntime} : null\n}\n\nfunction trimSetting(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0 ? value.trim() : undefined\n}\n\nfunction projectRuntimeStatus() {\n const core = useCoreStore.getState()\n const glasses = useGlassesStore.getState()\n const connection = useConnectionStore.getState()\n const cloudClient = useCloudClientStatusStore.getState()\n return {\n searching: core.searching,\n // Copy: the snapshot must not hand callers a mutable reference into the store.\n micRanking: [...core.micRanking],\n currentMic: core.currentMic,\n systemMicUnavailable: core.systemMicUnavailable,\n glassesConnected: glasses.connection.state === \"connected\",\n glassesFullyBooted: isGlassesReady(glasses.connection),\n bluetoothClassicConnected: glasses.bluetoothClassicConnected,\n coreStatus: connection.status,\n cloudClientStatus: cloudClient.status,\n cloudClientAudioTransport: cloudClient.audioTransport,\n }\n}\n\nexport type DevRuntimeStatusSnapshot = ReturnType<typeof projectRuntimeStatus>\n\nexport const dev = {\n /** The cloud-v2 core/runtime URL overrides. */\n cloudUrls: (): {core?: string; runtime?: string} => {\n const s = useSettingsStore.getState()\n return {core: s.getSetting(SETTINGS.cloud_core_url.key), runtime: s.getSetting(SETTINGS.cloud_runtime_url.key)}\n },\n /** Override the cloud-v2 URLs and reconnect the live client onto them. */\n setCloudUrls: (urls: {core?: string; runtime?: string}) => {\n const next = {...currentCloudUrlOverrides(), ...urls}\n const resolved = resolveCloudUrlReconnectTarget(next)\n if (resolved === null) {\n console.warn(\"engine.dev.setCloudUrls: ignoring partial cloud override without a resolvable sibling endpoint\")\n return\n }\n\n const s = useSettingsStore.getState()\n if (urls.core !== undefined) s.setSetting(SETTINGS.cloud_core_url.key, urls.core)\n if (urls.runtime !== undefined) s.setSetting(SETTINGS.cloud_runtime_url.key, urls.runtime)\n if (resolved === undefined) {\n cloudClientService.reconnect(null)\n } else {\n cloudClientService.reconnect(resolved)\n }\n },\n\n /** Tear down + rebuild the live cloud client (the dev \"reconnect\" button). */\n reconnectCloud: (): void => applyCloudUrlReconnect(),\n\n /** Current native (BLE-process) memory usage in MB — a dev/diagnostics gauge. */\n getMemoryMB: (): number => BluetoothSdk.getMemoryMB(),\n /**\n * Phone-side bluetooth runtime snapshot (the core store read-model: scan/mic/\n * search state) — the diagnostics/data-export surface. Shallow copy.\n */\n bluetoothStatus: (): Record<string, unknown> => {\n const {setCoreInfo: _setCoreInfo, reset: _reset, ...state} = useCoreStore.getState()\n return {...state}\n },\n\n /**\n * Side-load a miniapp being served from a dev machine (the `mentra dev` / CLI\n * flow) by its URL: probes `<url>/miniapp.json`, and on a reachable manifest\n * registers it into the single dev slot so it appears in `engine.miniapps`\n * and can be started. This is the OEM-host equivalent of the first-party\n * developer-URL screen — the registration itself is engine-internal, so a\n * host reaches it here rather than the internal registry. Rendering still\n * flows through the normal display path once the miniapp is started.\n */\n loadDevMiniapp: async (\n url: string,\n name?: string,\n ): Promise<{ok: true; packageName: string; name: string} | {ok: false; error: string}> => {\n const devUrl = url.trim().replace(/\\/+$/, \"\")\n if (!devUrl) return {ok: false, error: \"empty url\"}\n const result = await decideDevLaunchRoute(\"\", devUrl)\n if (result.decision !== \"live\") {\n return {ok: false, error: \"dev server unreachable, or no miniapp.json served there\"}\n }\n const manifest = result.manifest\n // The `mentra-miniapp dev` server puts the hot-reload/log sidecar on the\n // user port PLUS ONE — same convention as the first-party developer-URL\n // screen's deriveDevPort.\n let devPort: number | undefined\n try {\n const parsed = Number(new URL(devUrl).port)\n devPort = Number.isFinite(parsed) && parsed > 0 ? parsed + 1 : undefined\n } catch {\n devPort = undefined\n }\n const appName = name ?? manifest.name ?? \"Dev Miniapp\"\n registerDevApp({\n // The REAL manifest package: registerDevApp preserves it as\n // sourcePackageName (miniapp auth + dev-slot cleanup key off it) before\n // forcing packageName to the single dev slot.\n packageName: (manifest.packageName as string | undefined) ?? DEV_APP_PACKAGE_NAME,\n name: appName,\n iconUrl: manifest.icon ? new URL(manifest.icon, `${devUrl}/`).toString() : `${devUrl}/icon.png`,\n devUrl,\n devPort,\n type: manifest.type as DevAppRecord[\"type\"],\n permissions: manifest.permissions as DevAppRecord[\"permissions\"],\n hardwareRequirements: manifest.hardwareRequirements as DevAppRecord[\"hardwareRequirements\"],\n actions: manifest.actions as DevAppRecord[\"actions\"],\n })\n await useAppStatusStore.getState().refresh()\n return {ok: true, packageName: DEV_APP_PACKAGE_NAME, name: appName}\n },\n\n /** Current engine runtime status for engine-owned debug surfaces. */\n runtimeStatus: (): DevRuntimeStatusSnapshot => projectRuntimeStatus(),\n\n /** Subscribe to the projected engine runtime status; returns an unsubscribe. */\n onRuntimeStatus: (cb: (status: DevRuntimeStatusSnapshot) => void): (() => void) => {\n let last = JSON.stringify(projectRuntimeStatus())\n const notify = () => {\n const snap = projectRuntimeStatus()\n const key = JSON.stringify(snap)\n if (key === last) return\n last = key\n cb(snap)\n }\n const unsubscribers = [\n useCoreStore.subscribe(notify),\n useGlassesStore.subscribe(notify),\n useConnectionStore.subscribe(notify),\n useCloudClientStatusStore.subscribe(notify),\n ]\n return () => {\n unsubscribers.forEach((unsubscribe) => unsubscribe())\n }\n },\n}\n"]}
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/facades/dev.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dev facade — `engine.dev`: developer/debug surface over engine-owned state.\n * Backend/cloud URL overrides read+write the engine settings store; the cloud\n * URL setters reconnect the engine-owned cloud client onto the new endpoints;\n *\n * NOTE: the dev-time endpoint *resolution* (Metro-host auto-detect, env defaults)\n * still lives host-side in `@/services/cloudClient` during the migration; this\n * facade manages the explicit overrides + reconnect.\n */\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport {isGlassesReady} from \"../services/GlassesReadiness\"\nimport {useCloudClientStatusStore} from \"../stores/cloudClientStatus\"\nimport {useConnectionStore} from \"../stores/connection\"\nimport {useCoreStore} from \"../stores/core\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {useSettingsStore, SETTINGS} from \"../stores/settings\"\nimport {cloudClientService} from \"../services/CloudClientService\"\nimport {getConfigValues} from \"../runtime/bootstrap\"\nimport {decideDevLaunchRoute} from \"../utils/devMiniappLaunch\"\nimport {registerDevApp, DEV_APP_PACKAGE_NAME, type DevAppRecord} from \"../services/AppRegistry\"\nimport {useAppStatusStore} from \"../stores/apps\"\n\ntype CloudUrlOverrides = {core?: string; runtime?: string}\n\n/**\n * Reconnect the cloud client onto the current cloud-URL overrides. Explicit\n * partial overrides merge over the boot-resolved config (which carries the\n * host's Metro/env URL resolution); both empty clears the live override.\n */\nfunction applyCloudUrlReconnect(urls: CloudUrlOverrides = currentCloudUrlOverrides()): void {\n const resolved = resolveCloudUrlReconnectTarget(urls)\n if (resolved === undefined) {\n cloudClientService.reconnect(null)\n } else if (resolved) {\n cloudClientService.reconnect(resolved)\n } else {\n console.warn(\"engine.dev.setCloudUrls: partial cloud override missing boot-resolved sibling endpoint\")\n }\n}\n\nfunction currentCloudUrlOverrides(): CloudUrlOverrides {\n const s = useSettingsStore.getState()\n return {\n core: trimSetting(s.getSetting(SETTINGS.cloud_core_url.key)),\n runtime: trimSetting(s.getSetting(SETTINGS.cloud_runtime_url.key)),\n }\n}\n\nfunction resolveCloudUrlReconnectTarget(urls: CloudUrlOverrides): {core: string; runtime: string} | null | undefined {\n const core = trimSetting(urls.core)\n const runtime = trimSetting(urls.runtime)\n if (!core && !runtime) return undefined\n\n const config = getConfigValues()\n const resolvedCore = core || config.coreUrl?.trim()\n const resolvedRuntime = runtime || config.runtimeUrl?.trim()\n return resolvedCore && resolvedRuntime ? {core: resolvedCore, runtime: resolvedRuntime} : null\n}\n\nfunction trimSetting(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0 ? value.trim() : undefined\n}\n\nfunction projectRuntimeStatus() {\n const core = useCoreStore.getState()\n const glasses = useGlassesStore.getState()\n const connection = useConnectionStore.getState()\n const cloudClient = useCloudClientStatusStore.getState()\n return {\n searching: core.searching,\n // Copy: the snapshot must not hand callers a mutable reference into the store.\n micRanking: [...core.micRanking],\n currentMic: core.currentMic,\n systemMicUnavailable: core.systemMicUnavailable,\n glassesConnected: glasses.connection.state === \"connected\",\n glassesFullyBooted: isGlassesReady(glasses.connection),\n bluetoothClassicConnected: glasses.bluetoothClassicConnected,\n coreStatus: connection.status,\n cloudClientStatus: cloudClient.status,\n cloudClientAudioTransport: cloudClient.audioTransport,\n }\n}\n\nexport type DevRuntimeStatusSnapshot = ReturnType<typeof projectRuntimeStatus>\n\nexport const dev = {\n /** The cloud-v2 core/runtime URL overrides. */\n cloudUrls: (): {core?: string; runtime?: string} => {\n const s = useSettingsStore.getState()\n return {core: s.getSetting(SETTINGS.cloud_core_url.key), runtime: s.getSetting(SETTINGS.cloud_runtime_url.key)}\n },\n /** Override the cloud-v2 URLs and reconnect the live client onto them. */\n setCloudUrls: (urls: {core?: string; runtime?: string}) => {\n const next = {...currentCloudUrlOverrides(), ...urls}\n const resolved = resolveCloudUrlReconnectTarget(next)\n if (resolved === null) {\n console.warn(\"engine.dev.setCloudUrls: ignoring partial cloud override without a resolvable sibling endpoint\")\n return\n }\n\n const s = useSettingsStore.getState()\n if (urls.core !== undefined) s.setSetting(SETTINGS.cloud_core_url.key, urls.core)\n if (urls.runtime !== undefined) s.setSetting(SETTINGS.cloud_runtime_url.key, urls.runtime)\n if (resolved === undefined) {\n cloudClientService.reconnect(null)\n } else {\n cloudClientService.reconnect(resolved)\n }\n },\n\n /** Tear down + rebuild the live cloud client (the dev \"reconnect\" button). */\n reconnectCloud: (): void => applyCloudUrlReconnect(),\n\n /** Current native (BLE-process) memory usage in MB — a dev/diagnostics gauge. */\n getMemoryMB: (): number => BluetoothSdk.getMemoryMB(),\n /**\n * Phone-side bluetooth runtime snapshot (the core store read-model: scan/mic/\n * search state) — the diagnostics/data-export surface. Shallow copy.\n */\n bluetoothStatus: (): Record<string, unknown> => {\n const {setCoreInfo: _setCoreInfo, reset: _reset, ...state} = useCoreStore.getState()\n return {...state}\n },\n\n /**\n * Side-load a miniapp being served from a dev machine (the `mentra dev` / CLI\n * flow) by its URL: probes `<url>/miniapp.json`, and on a reachable manifest\n * registers it under its manifest package so it appears in `engine.miniapps`\n * and can coexist with other dev miniapps. This is the OEM-host equivalent\n * of the first-party\n * developer-URL screen — the registration itself is engine-internal, so a\n * host reaches it here rather than the internal registry. Rendering still\n * flows through the normal display path once the miniapp is started.\n */\n loadDevMiniapp: async (\n url: string,\n name?: string,\n ): Promise<{ok: true; packageName: string; name: string} | {ok: false; error: string}> => {\n const devUrl = url.trim().replace(/\\/+$/, \"\")\n if (!devUrl) return {ok: false, error: \"empty url\"}\n const result = await decideDevLaunchRoute(\"\", devUrl)\n if (result.decision !== \"live\") {\n return {ok: false, error: \"dev server unreachable, or no miniapp.json served there\"}\n }\n const manifest = result.manifest\n const appName = name ?? manifest.name ?? \"Dev Miniapp\"\n const packageName = (manifest.packageName as string | undefined) ?? DEV_APP_PACKAGE_NAME\n // Persist the host that answered — not the stale input IP — so home-tile\n // relaunches skip a dead LAN address after mDNS/Metro failover.\n const resolvedUrl = result.resolvedUrl || devUrl\n // The `mentra-miniapp dev` server puts the hot-reload/log sidecar on the\n // user port PLUS ONE — same convention as the first-party developer-URL\n // screen's deriveDevPort.\n let devPort: number | undefined\n try {\n const parsed = Number(new URL(resolvedUrl).port)\n devPort = Number.isFinite(parsed) && parsed > 0 ? parsed + 1 : undefined\n } catch {\n devPort = undefined\n }\n const existing = useAppStatusStore.getState().apps.find((app) => app.packageName === packageName)\n if (existing?.running) await useAppStatusStore.getState().stop(packageName)\n await registerDevApp({\n packageName,\n name: appName,\n iconUrl: manifest.icon ? new URL(manifest.icon, `${resolvedUrl}/`).toString() : `${resolvedUrl}/icon.png`,\n // Persist the host that answered — not the stale input IP.\n devUrl: resolvedUrl,\n devPort,\n type: manifest.type as DevAppRecord[\"type\"],\n permissions: manifest.permissions as DevAppRecord[\"permissions\"],\n hardwareRequirements: manifest.hardwareRequirements as DevAppRecord[\"hardwareRequirements\"],\n actions: manifest.actions as DevAppRecord[\"actions\"],\n })\n await useAppStatusStore.getState().refresh()\n return {ok: true, packageName, name: appName}\n },\n\n /** Current engine runtime status for engine-owned debug surfaces. */\n runtimeStatus: (): DevRuntimeStatusSnapshot => projectRuntimeStatus(),\n\n /** Subscribe to the projected engine runtime status; returns an unsubscribe. */\n onRuntimeStatus: (cb: (status: DevRuntimeStatusSnapshot) => void): (() => void) => {\n let last = JSON.stringify(projectRuntimeStatus())\n const notify = () => {\n const snap = projectRuntimeStatus()\n const key = JSON.stringify(snap)\n if (key === last) return\n last = key\n cb(snap)\n }\n const unsubscribers = [\n useCoreStore.subscribe(notify),\n useGlassesStore.subscribe(notify),\n useConnectionStore.subscribe(notify),\n useCloudClientStatusStore.subscribe(notify),\n ]\n return () => {\n unsubscribers.forEach((unsubscribe) => unsubscribe())\n }\n },\n}\n"]}