@glassly/engine 0.1.0-dev.61 → 0.1.0-dev.89

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 (147) hide show
  1. package/README.md +6 -2
  2. package/build/engine.d.ts +7 -2
  3. package/build/engine.d.ts.map +1 -1
  4. package/build/engine.js +3 -0
  5. package/build/engine.js.map +1 -1
  6. package/build/facades/display.d.ts +10 -3
  7. package/build/facades/display.d.ts.map +1 -1
  8. package/build/facades/display.js +11 -1
  9. package/build/facades/display.js.map +1 -1
  10. package/build/facades/displayMirror.d.ts +2 -6
  11. package/build/facades/displayMirror.d.ts.map +1 -1
  12. package/build/facades/displayMirror.js +7 -14
  13. package/build/facades/displayMirror.js.map +1 -1
  14. package/build/facades/glasses.d.ts +1 -0
  15. package/build/facades/glasses.d.ts.map +1 -1
  16. package/build/facades/glasses.js +2 -0
  17. package/build/facades/glasses.js.map +1 -1
  18. package/build/facades/ota.d.ts +3 -1
  19. package/build/facades/ota.d.ts.map +1 -1
  20. package/build/facades/ota.js +4 -2
  21. package/build/facades/ota.js.map +1 -1
  22. package/build/facades/phoneNotifications.d.ts +12 -2
  23. package/build/facades/phoneNotifications.d.ts.map +1 -1
  24. package/build/facades/phoneNotifications.js +30 -10
  25. package/build/facades/phoneNotifications.js.map +1 -1
  26. package/build/generated/releaseMetadata.js +3 -3
  27. package/build/generated/releaseMetadata.js.map +1 -1
  28. package/build/index.d.ts +2 -2
  29. package/build/index.d.ts.map +1 -1
  30. package/build/index.js +2 -2
  31. package/build/index.js.map +1 -1
  32. package/build/react/MentraLiveOtaFlow.d.ts +6 -1
  33. package/build/react/MentraLiveOtaFlow.d.ts.map +1 -1
  34. package/build/react/MentraLiveOtaFlow.js +136 -14
  35. package/build/react/MentraLiveOtaFlow.js.map +1 -1
  36. package/build/react/useMentraLiveOta.d.ts +5 -1
  37. package/build/react/useMentraLiveOta.d.ts.map +1 -1
  38. package/build/react/useMentraLiveOta.js +135 -58
  39. package/build/react/useMentraLiveOta.js.map +1 -1
  40. package/build/services/CustomDashboardService.d.ts +11 -10
  41. package/build/services/CustomDashboardService.d.ts.map +1 -1
  42. package/build/services/CustomDashboardService.js +70 -69
  43. package/build/services/CustomDashboardService.js.map +1 -1
  44. package/build/services/DashboardCoordinator.d.ts +26 -0
  45. package/build/services/DashboardCoordinator.d.ts.map +1 -0
  46. package/build/services/DashboardCoordinator.js +125 -0
  47. package/build/services/DashboardCoordinator.js.map +1 -0
  48. package/build/services/DeviceEventRouter.d.ts.map +1 -1
  49. package/build/services/DeviceEventRouter.js +5 -7
  50. package/build/services/DeviceEventRouter.js.map +1 -1
  51. package/build/services/DisplayProcessor.d.ts +3 -3
  52. package/build/services/DisplayProcessor.js +3 -3
  53. package/build/services/DisplayProcessor.js.map +1 -1
  54. package/build/services/LocalDisplayManager.d.ts +12 -2
  55. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  56. package/build/services/LocalDisplayManager.js +68 -14
  57. package/build/services/LocalDisplayManager.js.map +1 -1
  58. package/build/services/OtaInstallCoordinator.d.ts +2 -0
  59. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  60. package/build/services/OtaInstallCoordinator.js +21 -1
  61. package/build/services/OtaInstallCoordinator.js.map +1 -1
  62. package/build/services/PhoneNotificationsSync.d.ts +13 -0
  63. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  64. package/build/services/PhoneNotificationsSync.js +101 -9
  65. package/build/services/PhoneNotificationsSync.js.map +1 -1
  66. package/build/services/PhonePhotoCoordinator.js +1 -1
  67. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  68. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  69. package/build/services/PhoneStreamCoordinator.js +9 -6
  70. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  71. package/build/services/SceneRenderer.d.ts.map +1 -1
  72. package/build/services/SceneRenderer.js +5 -0
  73. package/build/services/SceneRenderer.js.map +1 -1
  74. package/build/services/StreamLifecycleController.d.ts +4 -0
  75. package/build/services/StreamLifecycleController.d.ts.map +1 -1
  76. package/build/services/StreamLifecycleController.js +4 -0
  77. package/build/services/StreamLifecycleController.js.map +1 -1
  78. package/build/services/effectiveCapabilities.d.ts +1 -1
  79. package/build/services/effectiveCapabilities.d.ts.map +1 -1
  80. package/build/services/effectiveCapabilities.js +9 -4
  81. package/build/services/effectiveCapabilities.js.map +1 -1
  82. package/build/services/iosNotificationAppCatalog.d.ts +13 -0
  83. package/build/services/iosNotificationAppCatalog.d.ts.map +1 -0
  84. package/build/services/iosNotificationAppCatalog.js +28 -0
  85. package/build/services/iosNotificationAppCatalog.js.map +1 -0
  86. package/build/services/otaInstallPolicy.d.ts +4 -0
  87. package/build/services/otaInstallPolicy.d.ts.map +1 -1
  88. package/build/services/otaInstallPolicy.js +4 -0
  89. package/build/services/otaInstallPolicy.js.map +1 -1
  90. package/build/stores/display.d.ts +4 -4
  91. package/build/stores/display.d.ts.map +1 -1
  92. package/build/stores/display.js +12 -36
  93. package/build/stores/display.js.map +1 -1
  94. package/build/stores/glasses.d.ts.map +1 -1
  95. package/build/stores/glasses.js +2 -0
  96. package/build/stores/glasses.js.map +1 -1
  97. package/build/stores/settings.d.ts.map +1 -1
  98. package/build/stores/settings.js +53 -2
  99. package/build/stores/settings.js.map +1 -1
  100. package/build/types/applet.d.ts +1 -1
  101. package/build/types/applet.js.map +1 -1
  102. package/build/types/capabilities/even-realities-g2.d.ts.map +1 -1
  103. package/build/types/capabilities/even-realities-g2.js +2 -2
  104. package/build/types/capabilities/even-realities-g2.js.map +1 -1
  105. package/build/types/hardware.d.ts.map +1 -1
  106. package/build/types/hardware.js +1 -0
  107. package/build/types/hardware.js.map +1 -1
  108. package/build/types/index.d.ts +1 -1
  109. package/build/types/index.d.ts.map +1 -1
  110. package/build/types/index.js +1 -1
  111. package/build/types/index.js.map +1 -1
  112. package/build/utils/display/composer/ColumnComposer.d.ts +1 -1
  113. package/build/utils/display/composer/ColumnComposer.js +1 -1
  114. package/build/utils/display/composer/ColumnComposer.js.map +1 -1
  115. package/package.json +8 -7
  116. package/src/engine.ts +3 -0
  117. package/src/facades/display.ts +11 -1
  118. package/src/facades/displayMirror.ts +7 -15
  119. package/src/facades/glasses.ts +2 -0
  120. package/src/facades/ota.ts +4 -2
  121. package/src/facades/phoneNotifications.ts +32 -10
  122. package/src/generated/releaseMetadata.ts +3 -3
  123. package/src/index.ts +2 -1
  124. package/src/react/MentraLiveOtaFlow.tsx +226 -41
  125. package/src/react/useMentraLiveOta.ts +146 -60
  126. package/src/services/CustomDashboardService.ts +67 -66
  127. package/src/services/DashboardCoordinator.ts +121 -0
  128. package/src/services/DeviceEventRouter.ts +5 -7
  129. package/src/services/DisplayProcessor.ts +3 -3
  130. package/src/services/LocalDisplayManager.ts +68 -16
  131. package/src/services/OtaInstallCoordinator.ts +21 -0
  132. package/src/services/PhoneNotificationsSync.ts +125 -9
  133. package/src/services/PhonePhotoCoordinator.ts +1 -1
  134. package/src/services/PhoneStreamCoordinator.ts +10 -6
  135. package/src/services/SceneRenderer.ts +4 -0
  136. package/src/services/StreamLifecycleController.ts +4 -0
  137. package/src/services/effectiveCapabilities.ts +9 -4
  138. package/src/services/iosNotificationAppCatalog.ts +39 -0
  139. package/src/services/otaInstallPolicy.ts +4 -0
  140. package/src/stores/display.ts +16 -48
  141. package/src/stores/glasses.ts +2 -0
  142. package/src/stores/settings.ts +53 -2
  143. package/src/types/applet.ts +1 -1
  144. package/src/types/capabilities/even-realities-g2.ts +3 -2
  145. package/src/types/hardware.ts +1 -0
  146. package/src/types/index.ts +1 -1
  147. package/src/utils/display/composer/ColumnComposer.ts +1 -1
@@ -1,24 +1,38 @@
1
1
  /**
2
2
  * phoneNotifications facade — `engine.phoneNotifications`: forward phone
3
- * notifications to the glasses, with a per-app blocklist. Android-only (the
4
- * NotificationListenerService); the getters return sensible defaults on iOS.
3
+ * notifications to the glasses, with a per-app blocklist.
5
4
  *
6
- * The per-app blocklist is an engine setting (auto-synced to the native
7
- * listener); the installed-apps list + listener permission are CrustModule.
8
- * Capture itself is controlled only by Android notification access and the
9
- * hidden operational kill switch.
5
+ * Android: apps come from the NotificationListenerService's installed-apps
6
+ * enumeration and the blocklist filters capture phone-side.
7
+ * iOS: apps are the seeded catalog plus what the glasses' ANCS client has
8
+ * reported posting notifications (`ios_notification_seen_apps`); the blocklist
9
+ * is mapped onto the G2's on-glass allowlist by PhoneNotificationsSync.
10
+ * Capture itself is controlled by Android notification access / iOS ANCS
11
+ * authorization (`glasses.ancsAuthorized`), not by this facade.
10
12
  */
11
13
  import { Platform } from "react-native";
12
14
  import CrustModule from "@glassly/crust";
13
15
  import { useSettingsStore, SETTINGS } from "../stores/settings";
16
+ import { useGlassesStore } from "../stores/glasses";
17
+ import { getKnownNotificationApps } from "../services/PhoneNotificationsSync";
14
18
  export const phoneNotifications = {
15
- /** The phone's installed apps (package, name, icon). (empty on iOS) */
19
+ /**
20
+ * Apps to show in the notification filter UI (package/bundle id, name, icon).
21
+ * Android: installed apps. iOS: seeded catalog ∪ glasses-reported apps
22
+ * (icons unavailable — iOS offers no cross-app icon lookup).
23
+ */
16
24
  installedApps: () => {
17
- if (Platform.OS !== "android")
25
+ if (Platform.OS === "android")
26
+ return CrustModule.getInstalledApps();
27
+ if (Platform.OS !== "ios")
18
28
  return Promise.resolve([]);
19
- return CrustModule.getInstalledApps();
29
+ return Promise.resolve(getKnownNotificationApps().map((app) => ({
30
+ packageName: app.appId,
31
+ appName: app.displayName,
32
+ icon: null,
33
+ })));
20
34
  },
21
- /** The per-app blocklist (package names whose notifications are NOT forwarded). */
35
+ /** The per-app blocklist (package/bundle ids whose notifications are NOT forwarded). */
22
36
  blocklist: () => {
23
37
  const b = useSettingsStore.getState().getSetting(SETTINGS.notifications_blocklist.key);
24
38
  return Array.isArray(b) ? b : [];
@@ -37,5 +51,11 @@ export const phoneNotifications = {
37
51
  return;
38
52
  return CrustModule.openNotificationListenerSettings();
39
53
  },
54
+ /**
55
+ * iOS: whether the connected glasses may read the phone's ANCS notification
56
+ * stream (the "Share System Notifications" Bluetooth consent). Always false
57
+ * on Android — Android capture is the notification listener instead.
58
+ */
59
+ ancsAuthorized: () => Boolean(useGlassesStore.getState().ancsAuthorized),
40
60
  };
41
61
  //# sourceMappingURL=phoneNotifications.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"phoneNotifications.js","sourceRoot":"","sources":["../../src/facades/phoneNotifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAA;AACrC,OAAO,WAAW,MAAM,gBAAgB,CAAA;AACxC,OAAO,EAAC,gBAAgB,EAAE,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAE7D,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,uEAAuE;IACvE,aAAa,EAAE,GAAgF,EAAE;QAC/F,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACzD,OAAO,WAAW,CAAC,gBAAgB,EAAE,CAAA;IACvC,CAAC;IAED,mFAAmF;IACnF,SAAS,EAAE,GAAa,EAAE;QACxB,MAAM,CAAC,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAA;QACtF,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAClC,CAAC;IACD,qCAAqC;IACrC,YAAY,EAAE,CAAC,YAAsB,EAAE,EAAE,CACvC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,uBAAuB,CAAC,GAAG,EAAE,YAAY,CAAC;IAE5F,qFAAqF;IACrF,qBAAqB,EAAE,GAAqB,EAAE;QAC5C,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC5D,OAAO,WAAW,CAAC,iCAAiC,EAAE,CAAA;IACxD,CAAC;IACD,yFAAyF;IACzF,yBAAyB,EAAE,GAAG,EAAE;QAC9B,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS;YAAE,OAAM;QACrC,OAAO,WAAW,CAAC,gCAAgC,EAAE,CAAA;IACvD,CAAC;CACF,CAAA","sourcesContent":["/**\n * phoneNotifications facade — `engine.phoneNotifications`: forward phone\n * notifications to the glasses, with a per-app blocklist. Android-only (the\n * NotificationListenerService); the getters return sensible defaults on iOS.\n *\n * The per-app blocklist is an engine setting (auto-synced to the native\n * listener); the installed-apps list + listener permission are CrustModule.\n * Capture itself is controlled only by Android notification access and the\n * hidden operational kill switch.\n */\nimport {Platform} from \"react-native\"\nimport CrustModule from \"@glassly/crust\"\nimport {useSettingsStore, SETTINGS} from \"../stores/settings\"\n\nexport const phoneNotifications = {\n /** The phone's installed apps (package, name, icon). (empty on iOS) */\n installedApps: (): Promise<Array<{packageName: string; appName: string; icon: string | null}>> => {\n if (Platform.OS !== \"android\") return Promise.resolve([])\n return CrustModule.getInstalledApps()\n },\n\n /** The per-app blocklist (package names whose notifications are NOT forwarded). */\n blocklist: (): string[] => {\n const b = useSettingsStore.getState().getSetting(SETTINGS.notifications_blocklist.key)\n return Array.isArray(b) ? b : []\n },\n /** Replace the per-app blocklist. */\n setBlocklist: (packageNames: string[]) =>\n useSettingsStore.getState().setSetting(SETTINGS.notifications_blocklist.key, packageNames),\n\n /** Does the app have the Android notification-listener permission? (false on iOS) */\n hasListenerPermission: (): Promise<boolean> => {\n if (Platform.OS !== \"android\") return Promise.resolve(false)\n return CrustModule.hasNotificationListenerPermission()\n },\n /** Open the OS settings to grant the notification-listener permission. (no-op on iOS) */\n requestListenerPermission: () => {\n if (Platform.OS !== \"android\") return\n return CrustModule.openNotificationListenerSettings()\n },\n}\n"]}
1
+ {"version":3,"file":"phoneNotifications.js","sourceRoot":"","sources":["../../src/facades/phoneNotifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAA;AACrC,OAAO,WAAW,MAAM,gBAAgB,CAAA;AACxC,OAAO,EAAC,gBAAgB,EAAE,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAC,wBAAwB,EAAC,MAAM,oCAAoC,CAAA;AAE3E,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC;;;;OAIG;IACH,aAAa,EAAE,GAAgF,EAAE;QAC/F,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS;YAAE,OAAO,WAAW,CAAC,gBAAgB,EAAE,CAAA;QACpE,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACrD,OAAO,OAAO,CAAC,OAAO,CACpB,wBAAwB,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACvC,WAAW,EAAE,GAAG,CAAC,KAAK;YACtB,OAAO,EAAE,GAAG,CAAC,WAAW;YACxB,IAAI,EAAE,IAAI;SACX,CAAC,CAAC,CACJ,CAAA;IACH,CAAC;IAED,wFAAwF;IACxF,SAAS,EAAE,GAAa,EAAE;QACxB,MAAM,CAAC,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAA;QACtF,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAClC,CAAC;IACD,qCAAqC;IACrC,YAAY,EAAE,CAAC,YAAsB,EAAE,EAAE,CACvC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,uBAAuB,CAAC,GAAG,EAAE,YAAY,CAAC;IAE5F,qFAAqF;IACrF,qBAAqB,EAAE,GAAqB,EAAE;QAC5C,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC5D,OAAO,WAAW,CAAC,iCAAiC,EAAE,CAAA;IACxD,CAAC;IACD,yFAAyF;IACzF,yBAAyB,EAAE,GAAG,EAAE;QAC9B,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS;YAAE,OAAM;QACrC,OAAO,WAAW,CAAC,gCAAgC,EAAE,CAAA;IACvD,CAAC;IAED;;;;OAIG;IACH,cAAc,EAAE,GAAY,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC,cAAc,CAAC;CAClF,CAAA","sourcesContent":["/**\n * phoneNotifications facade — `engine.phoneNotifications`: forward phone\n * notifications to the glasses, with a per-app blocklist.\n *\n * Android: apps come from the NotificationListenerService's installed-apps\n * enumeration and the blocklist filters capture phone-side.\n * iOS: apps are the seeded catalog plus what the glasses' ANCS client has\n * reported posting notifications (`ios_notification_seen_apps`); the blocklist\n * is mapped onto the G2's on-glass allowlist by PhoneNotificationsSync.\n * Capture itself is controlled by Android notification access / iOS ANCS\n * authorization (`glasses.ancsAuthorized`), not by this facade.\n */\nimport {Platform} from \"react-native\"\nimport CrustModule from \"@glassly/crust\"\nimport {useSettingsStore, SETTINGS} from \"../stores/settings\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {getKnownNotificationApps} from \"../services/PhoneNotificationsSync\"\n\nexport const phoneNotifications = {\n /**\n * Apps to show in the notification filter UI (package/bundle id, name, icon).\n * Android: installed apps. iOS: seeded catalog ∪ glasses-reported apps\n * (icons unavailable — iOS offers no cross-app icon lookup).\n */\n installedApps: (): Promise<Array<{packageName: string; appName: string; icon: string | null}>> => {\n if (Platform.OS === \"android\") return CrustModule.getInstalledApps()\n if (Platform.OS !== \"ios\") return Promise.resolve([])\n return Promise.resolve(\n getKnownNotificationApps().map((app) => ({\n packageName: app.appId,\n appName: app.displayName,\n icon: null,\n })),\n )\n },\n\n /** The per-app blocklist (package/bundle ids whose notifications are NOT forwarded). */\n blocklist: (): string[] => {\n const b = useSettingsStore.getState().getSetting(SETTINGS.notifications_blocklist.key)\n return Array.isArray(b) ? b : []\n },\n /** Replace the per-app blocklist. */\n setBlocklist: (packageNames: string[]) =>\n useSettingsStore.getState().setSetting(SETTINGS.notifications_blocklist.key, packageNames),\n\n /** Does the app have the Android notification-listener permission? (false on iOS) */\n hasListenerPermission: (): Promise<boolean> => {\n if (Platform.OS !== \"android\") return Promise.resolve(false)\n return CrustModule.hasNotificationListenerPermission()\n },\n /** Open the OS settings to grant the notification-listener permission. (no-op on iOS) */\n requestListenerPermission: () => {\n if (Platform.OS !== \"android\") return\n return CrustModule.openNotificationListenerSettings()\n },\n\n /**\n * iOS: whether the connected glasses may read the phone's ANCS notification\n * stream (the \"Share System Notifications\" Bluetooth consent). Always false\n * on Android — Android capture is the notification listener instead.\n */\n ancsAuthorized: (): boolean => Boolean(useGlassesStore.getState().ancsAuthorized),\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  export const ENGINE_RELEASE_METADATA = Object.freeze({
2
2
  "schemaVersion": 1,
3
3
  "familyBaseVersion": "0.1.0",
4
- "releaseIdentity": "0.1.0-dev.61",
5
- "releaseSetId": "glassly-0.1.0-dev.61",
6
- "sourceCommit": "a95e4c9e0146e47ed4e553613584abd265913759",
4
+ "releaseIdentity": "0.1.0-dev.89",
5
+ "releaseSetId": "glassly-0.1.0-dev.89",
6
+ "sourceCommit": "c66a621d66d70251e257f73c9a79ee1f8e079be9",
7
7
  "otaManifestUrl": null,
8
8
  "otaManifestSha256": null
9
9
  });
@@ -1 +1 @@
1
- {"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,uBAAuB,GAAoC,MAAM,CAAC,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,cAAc;IACjC,cAAc,EAAE,sBAAsB;IACtC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,IAAI;IACtB,mBAAmB,EAAE,IAAI;CAC1B,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface EngineReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"0.1.0\",\n \"releaseIdentity\": \"0.1.0-dev.61\",\n \"releaseSetId\": \"glassly-0.1.0-dev.61\",\n \"sourceCommit\": \"a95e4c9e0146e47ed4e553613584abd265913759\",\n \"otaManifestUrl\": null,\n \"otaManifestSha256\": null\n})\n"]}
1
+ {"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,uBAAuB,GAAoC,MAAM,CAAC,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,cAAc;IACjC,cAAc,EAAE,sBAAsB;IACtC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,IAAI;IACtB,mBAAmB,EAAE,IAAI;CAC1B,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface EngineReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"0.1.0\",\n \"releaseIdentity\": \"0.1.0-dev.89\",\n \"releaseSetId\": \"glassly-0.1.0-dev.89\",\n \"sourceCommit\": \"c66a621d66d70251e257f73c9a79ee1f8e079be9\",\n \"otaManifestUrl\": null,\n \"otaManifestSha256\": null\n})\n"]}
package/build/index.d.ts CHANGED
@@ -29,7 +29,7 @@ export type { CloudClientStatusSnapshot, MiniappAuthToken, InteropAuditEvent, Tt
29
29
  export { isGlassesConnected, isGlassesReady, isGlassesLinkLayerBusy, waitForGlassesReady, type GlassesConnectionStatus, type WaitForGlassesReadyOptions, } from "./services/GlassesReadiness";
30
30
  export { decideReconnect, decideConnectButtonAction, type ReconnectDecision, type ReconnectDecisionInput, type ConnectButtonAction, } from "./services/ConnectionCoordinator";
31
31
  export type { VersionInfo, MtkPatch, BesFirmware, VersionJson, OtaCheckResult, OtaCheckCurrentGlassesResult, OtaCheckCurrentGlassesOptions, } from "./services/OtaUpdateCheckService";
32
- export { MINIMUM_OTA_STATUS_BUILD, MAX_RETRIES, RETRY_INTERVAL_MS, PROGRESS_TIMEOUT_MS, DOWNLOAD_STUCK_TIMEOUT_MS, MTK_INSTALL_TIMEOUT_MS, GLOBAL_OTA_TIMEOUT_MS, PING_INTERVAL_MS, QUERY_REPLY_TIMEOUT_MS, OtaProgressMessages, } from "./services/otaInstallPolicy";
32
+ export { MINIMUM_OTA_STATUS_BUILD, MAX_RETRIES, RETRY_INTERVAL_MS, PROGRESS_TIMEOUT_MS, DOWNLOAD_STUCK_TIMEOUT_MS, MTK_INSTALL_TIMEOUT_MS, GLOBAL_OTA_TIMEOUT_MS, PING_INTERVAL_MS, QUERY_REPLY_TIMEOUT_MS, BES_RESTART_TIMEOUT_MS, OtaProgressMessages, } from "./services/otaInstallPolicy";
33
33
  export { deriveDisplayState } from "./services/otaDisplayState";
34
34
  export type { DisplayState } from "./services/otaDisplayState";
35
35
  export type { OtaProgress, OtaProgressStatus, OtaStatus, OtaUpdateInfo, ReleaseChangelog, OtaSnapshot, OtaInstallSnapshot, } from "./facades/ota";
@@ -46,6 +46,6 @@ export { DUMMY_APPLET, saveAppsOrder, getAppsOrder, sortAppsByPackageNamePriorit
46
46
  export { decideDevLaunchRoute, type DecideDevLaunchOptions, type DevLaunchResult, type DevManifest, } from "./utils/devMiniappLaunch";
47
47
  export { HardwareCompatibility, type CompatibilityResult } from "./utils/hardware";
48
48
  export { BgTimer, throttle, debounce } from "./utils/timers";
49
- export { HardwareType, HardwareRequirementLevel, DeviceTypes, ControllerTypes, HARDWARE_CAPABILITIES, getModelCapabilities, simulatedGlasses, evenRealitiesG1, evenRealitiesG2, mentraLive, vuzixZ100, mentraDisplay, nimo, } from "./types";
49
+ export { HardwareType, HardwareRequirementLevel, DeviceTypes, ControllerTypes, HARDWARE_CAPABILITIES, getModelCapabilities, simulatedGlasses, evenRealitiesG1, evenRealitiesG2, mentraLive, nimo, vuzixZ100, mentraDisplay, } from "./types";
50
50
  export type { HardwareRequirement, CameraCapabilities, DisplayCapabilities, MicrophoneCapabilities, SpeakerCapabilities, IMUCapabilities, ButtonCapabilities, LightCapabilities, PowerCapabilities, Capabilities, AppletType, AppPermissionType, AppletPermission, AppletInterface, ClientApp, } from "./types";
51
51
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/build/index.js CHANGED
@@ -31,7 +31,7 @@ export { isGlassesConnected, isGlassesReady, isGlassesLinkLayerBusy, waitForGlas
31
31
  export { decideReconnect, decideConnectButtonAction, } from "./services/ConnectionCoordinator";
32
32
  // OTA install policy (watchdog timings + failure copy) + display-state
33
33
  // derivation, consumed by the OTA screens and their tests.
34
- export { MINIMUM_OTA_STATUS_BUILD, MAX_RETRIES, RETRY_INTERVAL_MS, PROGRESS_TIMEOUT_MS, DOWNLOAD_STUCK_TIMEOUT_MS, MTK_INSTALL_TIMEOUT_MS, GLOBAL_OTA_TIMEOUT_MS, PING_INTERVAL_MS, QUERY_REPLY_TIMEOUT_MS, OtaProgressMessages, } from "./services/otaInstallPolicy";
34
+ export { MINIMUM_OTA_STATUS_BUILD, MAX_RETRIES, RETRY_INTERVAL_MS, PROGRESS_TIMEOUT_MS, DOWNLOAD_STUCK_TIMEOUT_MS, MTK_INSTALL_TIMEOUT_MS, GLOBAL_OTA_TIMEOUT_MS, PING_INTERVAL_MS, QUERY_REPLY_TIMEOUT_MS, BES_RESTART_TIMEOUT_MS, OtaProgressMessages, } from "./services/otaInstallPolicy";
35
35
  export { deriveDisplayState } from "./services/otaDisplayState";
36
36
  export { beginOtaAutoChain, clearOtaAutoChainReconnectWait, isOtaAutoChainActive, otaAutoChainFingerprint, otaAutoChainReconnectWaitRemaining, stopOtaAutoChain, tryAdvanceOtaAutoChain, MAX_OTA_AUTO_CHAIN_PASSES, OTA_AUTO_CHAIN_RECONNECT_TIMEOUT_MS, } from "./services/OtaAutoChain";
37
37
  export { BES_INSTALL_RESTART_MESSAGE, getOtaErrorMessage, shouldRequireGlassesRebootForBesFailure, shouldShowChangeWifiForOtaDownloadFailure, } from "./services/OtaErrorMapping";
@@ -47,5 +47,5 @@ export { decideDevLaunchRoute, } from "./utils/devMiniappLaunch";
47
47
  export { HardwareCompatibility } from "./utils/hardware";
48
48
  export { BgTimer, throttle, debounce } from "./utils/timers";
49
49
  // Hardware types and capability profiles.
50
- export { HardwareType, HardwareRequirementLevel, DeviceTypes, ControllerTypes, HARDWARE_CAPABILITIES, getModelCapabilities, simulatedGlasses, evenRealitiesG1, evenRealitiesG2, mentraLive, vuzixZ100, mentraDisplay, nimo, } from "./types";
50
+ export { HardwareType, HardwareRequirementLevel, DeviceTypes, ControllerTypes, HARDWARE_CAPABILITIES, getModelCapabilities, simulatedGlasses, evenRealitiesG1, evenRealitiesG2, mentraLive, nimo, vuzixZ100, mentraDisplay, } from "./types";
51
51
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,2EAA2E;AAC3E,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAA;AAyB/B,2EAA2E;AAC3E,6EAA6E;AAC7E,yEAAyE;AACzE,qEAAqE;AACrE,kDAAkD;AAClD,OAAO,EAAC,QAAQ,EAAE,UAAU,EAAC,MAAM,mBAAmB,CAAA;AACtD,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,GAGrB,MAAM,iCAAiC,CAAA;AAExC,4EAA4E;AAC5E,yEAAyE;AACzE,6EAA6E;AAC7E,OAAO,EAAC,QAAQ,EAAE,kBAAkB,EAAE,gBAAgB,EAAC,MAAM,6BAA6B,CAAA;AAS1F,OAAO,EAAC,wBAAwB,EAAE,gCAAgC,EAAC,MAAM,+BAA+B,CAAA;AAExG,8CAA8C;AAC9C,OAAO,EAAC,oBAAoB,EAAC,MAAM,kBAAkB,CAAA;AAGrD,2DAA2D;AAC3D,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,mBAAmB,GAGpB,MAAM,6BAA6B,CAAA;AACpC,yEAAyE;AACzE,OAAO,EACL,eAAe,EACf,yBAAyB,GAI1B,MAAM,kCAAkC,CAAA;AAazC,uEAAuE;AACvE,2DAA2D;AAC3D,OAAO,EACL,wBAAwB,EACxB,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAA;AAW7D,OAAO,EACL,iBAAiB,EACjB,8BAA8B,EAC9B,oBAAoB,EACpB,uBAAuB,EACvB,kCAAkC,EAClC,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,mCAAmC,GACpC,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,uCAAuC,EACvC,yCAAyC,GAC1C,MAAM,4BAA4B,CAAA;AAMnC,OAAO,EAAC,uBAAuB,EAAC,MAAM,6CAA6C,CAAA;AACnF,OAAO,EAAC,wBAAwB,EAAC,MAAM,wCAAwC,CAAA;AAe/E,+EAA+E;AAC/E,OAAO,EAAC,eAAe,EAAC,MAAM,qBAAqB,CAAA;AAEnD,yEAAyE;AACzE,6CAA6C;AAC7C,OAAO,EACL,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,6BAA6B,EAC7B,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,OAAO,EACP,QAAQ,EACR,OAAO,EACP,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,gBAAgB,GAGjB,MAAM,eAAe,CAAA;AAEtB,4EAA4E;AAC5E,OAAO,EACL,oBAAoB,GAIrB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,qBAAqB,EAA2B,MAAM,kBAAkB,CAAA;AAChF,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAC,MAAM,gBAAgB,CAAA;AAE1D,0CAA0C;AAC1C,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,WAAW,EACX,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,UAAU,EACV,SAAS,EACT,aAAa,EACb,IAAI,GACL,MAAM,SAAS,CAAA","sourcesContent":["/**\n * `@glassly/engine` — the OEM-facing main entry.\n *\n * The `engine` namespace (configure/start/stop + typed domain facades), the\n * public contract/read-model types, and the pure helpers host UI legitimately\n * renders with (decision functions, sort/order helpers, policy constants,\n * capability tables, timers). Judgment rule: read models, commands, pure\n * functions and types belong here; anything that mutates runtime state or\n * exposes a raw store/service remains private to the GlasslyOS host.\n * See cloud-v2/docs/issues/020-glasses-status-boundary/integration-review.md §D.\n */\n\n// The namespaced OEM-facing engine API (the \"(A) host API\"). See ./engine.\nexport {engine} from \"./engine\"\nexport type {\n ReportAttachmentInput,\n ReportContext,\n ReportDetails,\n ReportStatus,\n ReportTrigger,\n ReportSubmitResult,\n EngineSubmitReportInput,\n} from \"./facades/reports\"\nexport type {IslandNotification, IslandNotificationKind} from \"./facades/notifications\"\nexport type {WifiSearchResult} from \"./facades/glassesWifi\"\nexport type {IdentitySnapshot} from \"./services/PairingIdentity\"\nexport type {DisplayMirrorEvent} from \"./facades/displayMirror\"\nexport type {\n IslandConfigureOptions,\n IslandAuth,\n IslandConfigValues,\n IslandAnalytics,\n IslandUiSeams,\n ScanQrOptions,\n ScanQrResult,\n SubjectTokenType,\n} from \"./runtime/bootstrap\"\n\n// Settings contract: the typed key registry (schema descriptors — the same\n// surface engine.settings.descriptor()/keys() reads), the per-key React hook\n// (the hook layer, same precedent as the apps hooks below), and the pure\n// device-model key helpers. The raw useSettingsStore stays internal;\n// imperative access goes through engine.settings.\nexport {SETTINGS, useSetting} from \"./stores/settings\"\nexport {\n isCustomDashboardEligible,\n normalizeDashboardWidgets,\n DASHBOARD_WIDGET_IDS,\n type DashboardWidgetId,\n type DashboardWidgetSetting,\n} from \"./services/CustomDashboardModel\"\n\n// AI tier registry: the curated per-tier model dropdown options and helpers\n// the Settings > AI Models screen renders. Resolution itself runs inside\n// LocalMiniappRuntime; the screen only reads/writes the ai_model_* settings.\nexport {AI_TIERS, TIER_MODEL_OPTIONS, parseTierSetting} from \"./services/AiTierResolution\"\nexport type {AiTier, AiTierProvider, TierModelOption} from \"./services/AiTierResolution\"\n\n// Shared user memory timeline (engine.memory / Settings > Memory). Entry and\n// session shapes are canonical in @glassly/miniapp (the session.memory\n// surface); the stats read model is engine-side.\nexport type {MemoryStats} from \"./services/MemoryStore\"\nexport type {SpeakerProfile} from \"./services/SpeakerProfileStore\"\nexport type {EnrollOutcome} from \"./facades/speakers\"\nexport {MENTRA_LIVE_SETTING_KEYS, getBluetoothSettingKeysForDevice} from \"./stores/bluetoothSettingKeys\"\n\n// Runtime-shared constants and contract DTOs.\nexport {ISLAND_SETTINGS_KEYS} from \"./runtime/config\"\nexport type {CloudClientStatusSnapshot, MiniappAuthToken, InteropAuditEvent, TtsSynthesisResult} from \"./runtime/config\"\n\n// Pure readiness predicates over glasses connection state.\nexport {\n isGlassesConnected,\n isGlassesReady,\n isGlassesLinkLayerBusy,\n waitForGlassesReady,\n type GlassesConnectionStatus,\n type WaitForGlassesReadyOptions,\n} from \"./services/GlassesReadiness\"\n// Pure connect/reconnect decision helpers (host UI renders the outcome).\nexport {\n decideReconnect,\n decideConnectButtonAction,\n type ReconnectDecision,\n type ReconnectDecisionInput,\n type ConnectButtonAction,\n} from \"./services/ConnectionCoordinator\"\n\n// OTA read-model types for host OTA UI (progress screen, error mapping,\n// progress section) — the check/install machinery itself is internal.\nexport type {\n VersionInfo,\n MtkPatch,\n BesFirmware,\n VersionJson,\n OtaCheckResult,\n OtaCheckCurrentGlassesResult,\n OtaCheckCurrentGlassesOptions,\n} from \"./services/OtaUpdateCheckService\"\n// OTA install policy (watchdog timings + failure copy) + display-state\n// derivation, consumed by the OTA screens and their tests.\nexport {\n MINIMUM_OTA_STATUS_BUILD,\n MAX_RETRIES,\n RETRY_INTERVAL_MS,\n PROGRESS_TIMEOUT_MS,\n DOWNLOAD_STUCK_TIMEOUT_MS,\n MTK_INSTALL_TIMEOUT_MS,\n GLOBAL_OTA_TIMEOUT_MS,\n PING_INTERVAL_MS,\n QUERY_REPLY_TIMEOUT_MS,\n OtaProgressMessages,\n} from \"./services/otaInstallPolicy\"\nexport {deriveDisplayState} from \"./services/otaDisplayState\"\nexport type {DisplayState} from \"./services/otaDisplayState\"\nexport type {\n OtaProgress,\n OtaProgressStatus,\n OtaStatus,\n OtaUpdateInfo,\n ReleaseChangelog,\n OtaSnapshot,\n OtaInstallSnapshot,\n} from \"./facades/ota\"\nexport {\n beginOtaAutoChain,\n clearOtaAutoChainReconnectWait,\n isOtaAutoChainActive,\n otaAutoChainFingerprint,\n otaAutoChainReconnectWaitRemaining,\n stopOtaAutoChain,\n tryAdvanceOtaAutoChain,\n MAX_OTA_AUTO_CHAIN_PASSES,\n OTA_AUTO_CHAIN_RECONNECT_TIMEOUT_MS,\n} from \"./services/OtaAutoChain\"\nexport type {OtaAutoChainAdvanceResult} from \"./services/OtaAutoChain\"\nexport {\n BES_INSTALL_RESTART_MESSAGE,\n getOtaErrorMessage,\n shouldRequireGlassesRebootForBesFailure,\n shouldShowChangeWifiForOtaDownloadFailure,\n} from \"./services/OtaErrorMapping\"\n\n// Gallery read models: engine.gallery.onNotice payload types, the media\n// permission helper + display-name derivation host gallery UI uses, and the\n// glasses-camera DTO types (re-exported through the host @/types/asg shim).\nexport type {GalleryNotice, GalleryNoticeCode} from \"./services/asg/galleryNotices\"\nexport {MediaLibraryPermissions} from \"./utils/permissions/MediaLibraryPermissions\"\nexport {deriveGalleryDisplayName} from \"./utils/permissions/galleryDisplayName\"\nexport type {\n PhotoInfo,\n CaptureFile,\n CaptureGroup,\n GalleryResponse,\n ServerStatus,\n HealthResponse,\n GalleryEvent,\n} from \"./types/asg\"\n\n// Bluetooth SDK event types host UI subscribes to via engine facades (the\n// BluetoothSdk singleton passthrough itself is internal).\nexport type {PairFailureEvent, GlassesNotReadyEvent} from \"@glassly/bluetooth-sdk\"\n\n// Cloud connection status enum (read model; the connection store is internal).\nexport {WebSocketStatus} from \"./stores/connection\"\n\n// App-list hook layer + pure list helpers (the raw useAppStatusStore and\n// installAppStoreHooks wiring are internal).\nexport {\n DUMMY_APPLET,\n saveAppsOrder,\n getAppsOrder,\n sortAppsByPackageNamePriority,\n saveLastOpenTime,\n getLastOpenTime,\n sortAppsByLastOpenTime,\n useApps,\n useStart,\n useStop,\n useSetForeground,\n useClearForeground,\n useRefresh,\n useStopAll,\n useInstall,\n useUninstall,\n useActiveApps,\n useActiveBackgroundApps,\n useBackgroundApps,\n useActiveForegroundApp,\n useForegroundApp,\n useActiveBackgroundAppsCount,\n useLocalMiniApps,\n type StartOptions,\n type OrderMap,\n} from \"./stores/apps\"\n\n// Pure dev-miniapp launch-route decision (registration itself is internal).\nexport {\n decideDevLaunchRoute,\n type DecideDevLaunchOptions,\n type DevLaunchResult,\n type DevManifest,\n} from \"./utils/devMiniappLaunch\"\nexport {HardwareCompatibility, type CompatibilityResult} from \"./utils/hardware\"\nexport {BgTimer, throttle, debounce} from \"./utils/timers\"\n\n// Hardware types and capability profiles.\nexport {\n HardwareType,\n HardwareRequirementLevel,\n DeviceTypes,\n ControllerTypes,\n HARDWARE_CAPABILITIES,\n getModelCapabilities,\n simulatedGlasses,\n evenRealitiesG1,\n evenRealitiesG2,\n mentraLive,\n vuzixZ100,\n mentraDisplay,\n nimo,\n} from \"./types\"\nexport type {\n HardwareRequirement,\n CameraCapabilities,\n DisplayCapabilities,\n MicrophoneCapabilities,\n SpeakerCapabilities,\n IMUCapabilities,\n ButtonCapabilities,\n LightCapabilities,\n PowerCapabilities,\n Capabilities,\n AppletType,\n AppPermissionType,\n AppletPermission,\n AppletInterface,\n ClientApp,\n} from \"./types\"\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,2EAA2E;AAC3E,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAA;AAyB/B,2EAA2E;AAC3E,6EAA6E;AAC7E,yEAAyE;AACzE,qEAAqE;AACrE,kDAAkD;AAClD,OAAO,EAAC,QAAQ,EAAE,UAAU,EAAC,MAAM,mBAAmB,CAAA;AACtD,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,GAGrB,MAAM,iCAAiC,CAAA;AAExC,4EAA4E;AAC5E,yEAAyE;AACzE,6EAA6E;AAC7E,OAAO,EAAC,QAAQ,EAAE,kBAAkB,EAAE,gBAAgB,EAAC,MAAM,6BAA6B,CAAA;AAS1F,OAAO,EAAC,wBAAwB,EAAE,gCAAgC,EAAC,MAAM,+BAA+B,CAAA;AAExG,8CAA8C;AAC9C,OAAO,EAAC,oBAAoB,EAAC,MAAM,kBAAkB,CAAA;AAGrD,2DAA2D;AAC3D,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,mBAAmB,GAGpB,MAAM,6BAA6B,CAAA;AACpC,yEAAyE;AACzE,OAAO,EACL,eAAe,EACf,yBAAyB,GAI1B,MAAM,kCAAkC,CAAA;AAazC,uEAAuE;AACvE,2DAA2D;AAC3D,OAAO,EACL,wBAAwB,EACxB,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAA;AAW7D,OAAO,EACL,iBAAiB,EACjB,8BAA8B,EAC9B,oBAAoB,EACpB,uBAAuB,EACvB,kCAAkC,EAClC,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,mCAAmC,GACpC,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,uCAAuC,EACvC,yCAAyC,GAC1C,MAAM,4BAA4B,CAAA;AAMnC,OAAO,EAAC,uBAAuB,EAAC,MAAM,6CAA6C,CAAA;AACnF,OAAO,EAAC,wBAAwB,EAAC,MAAM,wCAAwC,CAAA;AAe/E,+EAA+E;AAC/E,OAAO,EAAC,eAAe,EAAC,MAAM,qBAAqB,CAAA;AAEnD,yEAAyE;AACzE,6CAA6C;AAC7C,OAAO,EACL,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,6BAA6B,EAC7B,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,OAAO,EACP,QAAQ,EACR,OAAO,EACP,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,gBAAgB,GAGjB,MAAM,eAAe,CAAA;AAEtB,4EAA4E;AAC5E,OAAO,EACL,oBAAoB,GAIrB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,qBAAqB,EAA2B,MAAM,kBAAkB,CAAA;AAChF,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAC,MAAM,gBAAgB,CAAA;AAE1D,0CAA0C;AAC1C,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,WAAW,EACX,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,UAAU,EACV,IAAI,EACJ,SAAS,EACT,aAAa,GACd,MAAM,SAAS,CAAA","sourcesContent":["/**\n * `@glassly/engine` — the OEM-facing main entry.\n *\n * The `engine` namespace (configure/start/stop + typed domain facades), the\n * public contract/read-model types, and the pure helpers host UI legitimately\n * renders with (decision functions, sort/order helpers, policy constants,\n * capability tables, timers). Judgment rule: read models, commands, pure\n * functions and types belong here; anything that mutates runtime state or\n * exposes a raw store/service remains private to the GlasslyOS host.\n * See cloud-v2/docs/issues/020-glasses-status-boundary/integration-review.md §D.\n */\n\n// The namespaced OEM-facing engine API (the \"(A) host API\"). See ./engine.\nexport {engine} from \"./engine\"\nexport type {\n ReportAttachmentInput,\n ReportContext,\n ReportDetails,\n ReportStatus,\n ReportTrigger,\n ReportSubmitResult,\n EngineSubmitReportInput,\n} from \"./facades/reports\"\nexport type {IslandNotification, IslandNotificationKind} from \"./facades/notifications\"\nexport type {WifiSearchResult} from \"./facades/glassesWifi\"\nexport type {IdentitySnapshot} from \"./services/PairingIdentity\"\nexport type {DisplayMirrorEvent} from \"./facades/displayMirror\"\nexport type {\n IslandConfigureOptions,\n IslandAuth,\n IslandConfigValues,\n IslandAnalytics,\n IslandUiSeams,\n ScanQrOptions,\n ScanQrResult,\n SubjectTokenType,\n} from \"./runtime/bootstrap\"\n\n// Settings contract: the typed key registry (schema descriptors — the same\n// surface engine.settings.descriptor()/keys() reads), the per-key React hook\n// (the hook layer, same precedent as the apps hooks below), and the pure\n// device-model key helpers. The raw useSettingsStore stays internal;\n// imperative access goes through engine.settings.\nexport {SETTINGS, useSetting} from \"./stores/settings\"\nexport {\n isCustomDashboardEligible,\n normalizeDashboardWidgets,\n DASHBOARD_WIDGET_IDS,\n type DashboardWidgetId,\n type DashboardWidgetSetting,\n} from \"./services/CustomDashboardModel\"\n\n// AI tier registry: the curated per-tier model dropdown options and helpers\n// the Settings > AI Models screen renders. Resolution itself runs inside\n// LocalMiniappRuntime; the screen only reads/writes the ai_model_* settings.\nexport {AI_TIERS, TIER_MODEL_OPTIONS, parseTierSetting} from \"./services/AiTierResolution\"\nexport type {AiTier, AiTierProvider, TierModelOption} from \"./services/AiTierResolution\"\n\n// Shared user memory timeline (engine.memory / Settings > Memory). Entry and\n// session shapes are canonical in @glassly/miniapp (the session.memory\n// surface); the stats read model is engine-side.\nexport type {MemoryStats} from \"./services/MemoryStore\"\nexport type {SpeakerProfile} from \"./services/SpeakerProfileStore\"\nexport type {EnrollOutcome} from \"./facades/speakers\"\nexport {MENTRA_LIVE_SETTING_KEYS, getBluetoothSettingKeysForDevice} from \"./stores/bluetoothSettingKeys\"\n\n// Runtime-shared constants and contract DTOs.\nexport {ISLAND_SETTINGS_KEYS} from \"./runtime/config\"\nexport type {CloudClientStatusSnapshot, MiniappAuthToken, InteropAuditEvent, TtsSynthesisResult} from \"./runtime/config\"\n\n// Pure readiness predicates over glasses connection state.\nexport {\n isGlassesConnected,\n isGlassesReady,\n isGlassesLinkLayerBusy,\n waitForGlassesReady,\n type GlassesConnectionStatus,\n type WaitForGlassesReadyOptions,\n} from \"./services/GlassesReadiness\"\n// Pure connect/reconnect decision helpers (host UI renders the outcome).\nexport {\n decideReconnect,\n decideConnectButtonAction,\n type ReconnectDecision,\n type ReconnectDecisionInput,\n type ConnectButtonAction,\n} from \"./services/ConnectionCoordinator\"\n\n// OTA read-model types for host OTA UI (progress screen, error mapping,\n// progress section) — the check/install machinery itself is internal.\nexport type {\n VersionInfo,\n MtkPatch,\n BesFirmware,\n VersionJson,\n OtaCheckResult,\n OtaCheckCurrentGlassesResult,\n OtaCheckCurrentGlassesOptions,\n} from \"./services/OtaUpdateCheckService\"\n// OTA install policy (watchdog timings + failure copy) + display-state\n// derivation, consumed by the OTA screens and their tests.\nexport {\n MINIMUM_OTA_STATUS_BUILD,\n MAX_RETRIES,\n RETRY_INTERVAL_MS,\n PROGRESS_TIMEOUT_MS,\n DOWNLOAD_STUCK_TIMEOUT_MS,\n MTK_INSTALL_TIMEOUT_MS,\n GLOBAL_OTA_TIMEOUT_MS,\n PING_INTERVAL_MS,\n QUERY_REPLY_TIMEOUT_MS,\n BES_RESTART_TIMEOUT_MS,\n OtaProgressMessages,\n} from \"./services/otaInstallPolicy\"\nexport {deriveDisplayState} from \"./services/otaDisplayState\"\nexport type {DisplayState} from \"./services/otaDisplayState\"\nexport type {\n OtaProgress,\n OtaProgressStatus,\n OtaStatus,\n OtaUpdateInfo,\n ReleaseChangelog,\n OtaSnapshot,\n OtaInstallSnapshot,\n} from \"./facades/ota\"\nexport {\n beginOtaAutoChain,\n clearOtaAutoChainReconnectWait,\n isOtaAutoChainActive,\n otaAutoChainFingerprint,\n otaAutoChainReconnectWaitRemaining,\n stopOtaAutoChain,\n tryAdvanceOtaAutoChain,\n MAX_OTA_AUTO_CHAIN_PASSES,\n OTA_AUTO_CHAIN_RECONNECT_TIMEOUT_MS,\n} from \"./services/OtaAutoChain\"\nexport type {OtaAutoChainAdvanceResult} from \"./services/OtaAutoChain\"\nexport {\n BES_INSTALL_RESTART_MESSAGE,\n getOtaErrorMessage,\n shouldRequireGlassesRebootForBesFailure,\n shouldShowChangeWifiForOtaDownloadFailure,\n} from \"./services/OtaErrorMapping\"\n\n// Gallery read models: engine.gallery.onNotice payload types, the media\n// permission helper + display-name derivation host gallery UI uses, and the\n// glasses-camera DTO types (re-exported through the host @/types/asg shim).\nexport type {GalleryNotice, GalleryNoticeCode} from \"./services/asg/galleryNotices\"\nexport {MediaLibraryPermissions} from \"./utils/permissions/MediaLibraryPermissions\"\nexport {deriveGalleryDisplayName} from \"./utils/permissions/galleryDisplayName\"\nexport type {\n PhotoInfo,\n CaptureFile,\n CaptureGroup,\n GalleryResponse,\n ServerStatus,\n HealthResponse,\n GalleryEvent,\n} from \"./types/asg\"\n\n// Bluetooth SDK event types host UI subscribes to via engine facades (the\n// BluetoothSdk singleton passthrough itself is internal).\nexport type {PairFailureEvent, GlassesNotReadyEvent} from \"@glassly/bluetooth-sdk\"\n\n// Cloud connection status enum (read model; the connection store is internal).\nexport {WebSocketStatus} from \"./stores/connection\"\n\n// App-list hook layer + pure list helpers (the raw useAppStatusStore and\n// installAppStoreHooks wiring are internal).\nexport {\n DUMMY_APPLET,\n saveAppsOrder,\n getAppsOrder,\n sortAppsByPackageNamePriority,\n saveLastOpenTime,\n getLastOpenTime,\n sortAppsByLastOpenTime,\n useApps,\n useStart,\n useStop,\n useSetForeground,\n useClearForeground,\n useRefresh,\n useStopAll,\n useInstall,\n useUninstall,\n useActiveApps,\n useActiveBackgroundApps,\n useBackgroundApps,\n useActiveForegroundApp,\n useForegroundApp,\n useActiveBackgroundAppsCount,\n useLocalMiniApps,\n type StartOptions,\n type OrderMap,\n} from \"./stores/apps\"\n\n// Pure dev-miniapp launch-route decision (registration itself is internal).\nexport {\n decideDevLaunchRoute,\n type DecideDevLaunchOptions,\n type DevLaunchResult,\n type DevManifest,\n} from \"./utils/devMiniappLaunch\"\nexport {HardwareCompatibility, type CompatibilityResult} from \"./utils/hardware\"\nexport {BgTimer, throttle, debounce} from \"./utils/timers\"\n\n// Hardware types and capability profiles.\nexport {\n HardwareType,\n HardwareRequirementLevel,\n DeviceTypes,\n ControllerTypes,\n HARDWARE_CAPABILITIES,\n getModelCapabilities,\n simulatedGlasses,\n evenRealitiesG1,\n evenRealitiesG2,\n mentraLive,\n nimo,\n vuzixZ100,\n mentraDisplay,\n} from \"./types\"\nexport type {\n HardwareRequirement,\n CameraCapabilities,\n DisplayCapabilities,\n MicrophoneCapabilities,\n SpeakerCapabilities,\n IMUCapabilities,\n ButtonCapabilities,\n LightCapabilities,\n PowerCapabilities,\n Capabilities,\n AppletType,\n AppPermissionType,\n AppletPermission,\n AppletInterface,\n ClientApp,\n} from \"./types\"\n"]}
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { type StyleProp, type ViewStyle } from "react-native";
3
- import { type MentraLiveOtaFlowPage } from "./useMentraLiveOta";
3
+ import { type MentraLiveOtaController, type MentraLiveOtaFlowPage } from "./useMentraLiveOta";
4
4
  export type { MentraLiveOtaFlowPage } from "./useMentraLiveOta";
5
5
  export type MentraLiveOtaFlowTheme = {
6
6
  background: string;
@@ -36,4 +36,9 @@ export type MentraLiveOtaFlowProps = {
36
36
  style?: StyleProp<ViewStyle>;
37
37
  };
38
38
  export declare function MentraLiveOtaFlow({ allowDevSkip, deviceName, initialPage, initializeRuntime, onFinished, onFirmwareRestartingChange, onOpenWifiSetup, style, superMode, theme, translate, }: MentraLiveOtaFlowProps): React.JSX.Element;
39
+ export declare function ChangelogList({ changelogs, colors, title, }: {
40
+ changelogs: MentraLiveOtaController["state"]["changelogs"];
41
+ colors: MentraLiveOtaFlowTheme;
42
+ title: string;
43
+ }): React.JSX.Element | null;
39
44
  //# sourceMappingURL=MentraLiveOtaFlow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MentraLiveOtaFlow.d.ts","sourceRoot":"","sources":["../../src/react/MentraLiveOtaFlow.tsx"],"names":[],"mappings":"AACA,OAAO,KAAgB,MAAM,OAAO,CAAA;AACpC,OAAO,EAOL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAA;AAIrB,OAAO,EAAiD,KAAK,qBAAqB,EAAC,MAAM,oBAAoB,CAAA;AAE7G,YAAY,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAA;AAE7D,MAAM,MAAM,sBAAsB,GAAG;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAA;AAElG,MAAM,MAAM,sBAAsB,GAAG;IACnC,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,qBAAqB,CAAA;IACnC,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,+EAA+E;IAC/E,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,0EAA0E;IAC1E,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B,oGAAoG;IACpG,0BAA0B,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,KAAK,IAAI,CAAA;IACnF,0DAA0D;IAC1D,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,gFAAgF;IAChF,SAAS,CAAC,EAAE,0BAA0B,CAAA;IACtC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAA;IACvC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAC7B,CAAA;AA4DD,wBAAgB,iBAAiB,CAAC,EAChC,YAAwD,EACxD,UAA0B,EAC1B,WAAqB,EACrB,iBAAwB,EACxB,UAAU,EACV,0BAA0B,EAC1B,eAAe,EACf,KAAK,EACL,SAAiB,EACjB,KAAK,EACL,SAA4B,GAC7B,EAAE,sBAAsB,qBA0BxB"}
1
+ {"version":3,"file":"MentraLiveOtaFlow.d.ts","sourceRoot":"","sources":["../../src/react/MentraLiveOtaFlow.tsx"],"names":[],"mappings":"AACA,OAAO,KAAgB,MAAM,OAAO,CAAA;AACpC,OAAO,EAOL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAA;AAKrB,OAAO,EAGL,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC3B,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAA;AAE7D,MAAM,MAAM,sBAAsB,GAAG;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAA;AAElG,MAAM,MAAM,sBAAsB,GAAG;IACnC,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,qBAAqB,CAAA;IACnC,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,+EAA+E;IAC/E,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,0EAA0E;IAC1E,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B,oGAAoG;IACpG,0BAA0B,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,KAAK,IAAI,CAAA;IACnF,0DAA0D;IAC1D,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,gFAAgF;IAChF,SAAS,CAAC,EAAE,0BAA0B,CAAA;IACtC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAA;IACvC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAC7B,CAAA;AA4ED,wBAAgB,iBAAiB,CAAC,EAChC,YAAwD,EACxD,UAA0B,EAC1B,WAAqB,EACrB,iBAAwB,EACxB,UAAU,EACV,0BAA0B,EAC1B,eAAe,EACf,KAAK,EACL,SAAiB,EACjB,KAAK,EACL,SAA4B,GAC7B,EAAE,sBAAsB,qBA0BxB;AA+bD,wBAAgB,aAAa,CAAC,EAC5B,UAAU,EACV,MAAM,EACN,KAAK,GACN,EAAE;IACD,UAAU,EAAE,uBAAuB,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAA;IAC1D,MAAM,EAAE,sBAAsB,CAAA;IAC9B,KAAK,EAAE,MAAM,CAAA;CACd,4BA4BA"}
@@ -2,9 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  /* eslint-disable react-native/no-raw-text -- BodyText and PercentText are local Text wrappers. */
3
3
  import { useMemo } from "react";
4
4
  import { ActivityIndicator, Pressable, ScrollView, StyleSheet, Text, View, } from "react-native";
5
+ import { useMarkdown } from "react-native-marked";
5
6
  import { SafeAreaView } from "react-native-safe-area-context";
6
7
  import Svg, { Path, Rect } from "react-native-svg";
7
- import { useMentraLiveOta } from "./useMentraLiveOta";
8
+ import { MINIMUM_OTA_BATTERY_LEVEL, useMentraLiveOta, } from "./useMentraLiveOta";
8
9
  const DEFAULT_THEME = {
9
10
  background: "#FFFFFF",
10
11
  border: "#D7DFDA",
@@ -16,11 +17,19 @@ const DEFAULT_THEME = {
16
17
  };
17
18
  const ENGLISH_COPY = {
18
19
  "common:continue": "Continue",
20
+ "common:done": "Done",
19
21
  "ota:checkingForUpdates": "Checking for updates",
20
22
  "ota:checkingForUpdatesMessage": "Connected devices will perform automatic updates. Automatic updates can be disabled in Device Settings",
23
+ "ota:finishingUpdate": "Finishing your update",
24
+ "ota:checkingAdditionalUpdates": "Checking whether your glasses need any additional updates.",
21
25
  "ota:updateAvailable": "{{deviceName}} Update Available",
26
+ "ota:batteryRequiredTitle": "Charge {{deviceName}} to Update",
27
+ "ota:batteryRequiredMessage": "{{deviceName}} is currently at {{batteryLevel}}%. Charge it to at least {{minimumBatteryLevel}}% before updating.",
28
+ "ota:batteryRequiredLiveUpdate": "This screen will update automatically as the battery charges.",
22
29
  "ota:updateConnectWifi": "Connect your {{deviceName}} to WiFi to install the update.",
30
+ "ota:wifiRequiredTitle": "WiFi Needed for Update",
23
31
  "ota:updateDescription": "A new update is available for your glasses. We recommend updating now for the best experience.",
32
+ "ota:updateSequenceMessage": "Your glasses may install more than one update and restart several times. Keep them nearby until finished.",
24
33
  "ota:releaseTransition": "{{fromVersion}} → {{toVersion}}",
25
34
  "ota:releaseTransitionUnknown": "Current version unknown → {{toVersion}}",
26
35
  "ota:updatedToVersion": "Updated to {{version}}",
@@ -29,6 +38,8 @@ const ENGLISH_COPY = {
29
38
  "ota:updateNow": "Update Now",
30
39
  "ota:setupWifi": "Setup WiFi",
31
40
  "ota:updateLater": "Later",
41
+ "ota:updateComplete": "Update complete",
42
+ "ota:whatsNew": "What's new",
32
43
  "ota:upToDate": "Up To Date",
33
44
  "ota:devBuild": "Development Build",
34
45
  "ota:devBuildNoOta": "This mobile app is a development build, so automatic glasses updates are disabled. Use the developer settings manifest override to update them manually.",
@@ -41,6 +52,9 @@ const ENGLISH_COPY = {
41
52
  "ota:versionChangeRestarting": "Installing a different version…",
42
53
  "ota:versionChangeVerifying": "Verifying your glasses…",
43
54
  "ota:versionChangeKeepNearby": "Keep your glasses nearby and connected. They will restart on their own.",
55
+ "ota:restartingGlasses": "Restarting {{deviceName}}…",
56
+ "ota:restartingGlassesMessage": "The update is installed. Keep your glasses nearby and leave this screen open while they finish starting.",
57
+ "ota:restartingGlassesAutomatic": "We'll continue automatically when they're ready.",
44
58
  "ota:versionChangeComplete": "Version Change Complete",
45
59
  "ota:versionChangeCompleteMessage": "Your glasses are now on the required version. Their settings were reset and are being restored automatically.",
46
60
  "ota:versionChangeFirmwarePassComplete": "Firmware updated",
@@ -72,21 +86,36 @@ function OtaFlowContent({ allowDevSkip, colors, controller, deviceName, superMod
72
86
  if (state.screen === "checking") {
73
87
  return (_jsxs(FlowPage, { colors: colors, icon: "download", title: translate("ota:checkingForUpdates"), children: [_jsx(BodyText, { colors: colors, children: translate("ota:checkingForUpdatesMessage") }), _jsx(ActivityIndicator, { size: "large", color: colors.foreground })] }));
74
88
  }
89
+ if (state.screen === "battery_required") {
90
+ return (_jsxs(FlowPage, { actions: _jsxs(_Fragment, { children: [_jsx(FlowButton, { colors: colors, disabled: true, label: translate("ota:updateNow"), onPress: controller.install }), state.canDismiss ? (_jsx(FlowButton, { colors: colors, label: translate("ota:updateLater"), onPress: controller.finish, secondary: true })) : null] }), colors: colors, icon: "alert", title: translate("ota:batteryRequiredTitle", { deviceName }), children: [_jsx(BodyText, { colors: colors, children: translate("ota:batteryRequiredMessage", {
91
+ batteryLevel: String(state.batteryLevel),
92
+ deviceName,
93
+ minimumBatteryLevel: String(MINIMUM_OTA_BATTERY_LEVEL),
94
+ }) }), _jsx(BodyText, { colors: colors, children: translate("ota:batteryRequiredLiveUpdate") })] }));
95
+ }
96
+ if (state.screen === "finishing") {
97
+ return (_jsxs(FlowPage, { colors: colors, icon: "download", title: translate("ota:finishingUpdate"), children: [_jsx(BodyText, { colors: colors, children: translate("ota:checkingAdditionalUpdates") }), _jsx(ActivityIndicator, { size: "large", color: colors.foreground })] }));
98
+ }
75
99
  if (state.screen === "update_available" || state.screen === "wifi_required") {
76
- return (_jsxs(FlowPage, { colors: colors, icon: "download", title: translate(state.versionChange ? "ota:downgradeAvailable" : "ota:updateAvailable", { deviceName }), actions: _jsxs(_Fragment, { children: [_jsx(FlowButton, { colors: colors, disabled: !state.wifiStatusKnown, label: translate(state.screen === "wifi_required" ? "ota:setupWifi" : "ota:updateNow"), onPress: state.screen === "wifi_required" ? controller.openWifiSetup : controller.install }), state.canDismiss ? (_jsx(FlowButton, { colors: colors, label: translate("ota:updateLater"), onPress: controller.finish, secondary: true })) : null, allowDevSkip && state.updateRequired ? (_jsx(FlowButton, { colors: colors, label: "Skip (dev only)", onPress: controller.finish, secondary: true })) : null] }), children: [state.releaseTransition ? (_jsx(BodyText, { colors: colors, children: state.releaseTransition.fromVersion
100
+ const titleKey = state.screen === "wifi_required"
101
+ ? "ota:wifiRequiredTitle"
102
+ : state.versionChange
103
+ ? "ota:downgradeAvailable"
104
+ : "ota:updateAvailable";
105
+ return (_jsxs(FlowPage, { colors: colors, icon: "download", title: translate(titleKey, { deviceName }), actions: _jsxs(_Fragment, { children: [_jsx(FlowButton, { colors: colors, disabled: !state.wifiStatusKnown, label: translate(state.screen === "wifi_required" ? "ota:setupWifi" : "ota:updateNow"), onPress: state.screen === "wifi_required" ? controller.openWifiSetup : controller.install }), state.canDismiss ? (_jsx(FlowButton, { colors: colors, label: translate("ota:updateLater"), onPress: controller.finish, secondary: true })) : null, allowDevSkip && state.updateRequired ? (_jsx(FlowButton, { colors: colors, label: "Skip (dev only)", onPress: controller.finish, secondary: true })) : null] }), children: [state.releaseTransition ? (_jsx(BodyText, { colors: colors, children: state.releaseTransition.fromVersion
77
106
  ? translate("ota:releaseTransition", {
78
107
  fromVersion: state.releaseTransition.fromVersion,
79
108
  toVersion: state.releaseTransition.toVersion,
80
109
  })
81
110
  : translate("ota:releaseTransitionUnknown", { toVersion: state.releaseTransition.toVersion }) })) : null, _jsx(BodyText, { colors: colors, children: state.screen === "wifi_required"
82
111
  ? translate("ota:updateConnectWifi", { deviceName })
83
- : translate(state.versionChange ? "ota:downgradeDescription" : "ota:updateDescription") })] }));
112
+ : translate(state.versionChange ? "ota:downgradeDescription" : "ota:updateDescription") }), _jsx(BodyText, { colors: colors, children: translate("ota:updateSequenceMessage") })] }));
84
113
  }
85
114
  if (state.screen === "dev_build") {
86
115
  return (_jsx(FlowPage, { actions: _jsx(FlowButton, { colors: colors, label: translate("common:continue"), onPress: controller.finish }), colors: colors, icon: "settings", title: translate("ota:devBuild"), children: _jsx(BodyText, { colors: colors, children: translate("ota:devBuildNoOta") }) }));
87
116
  }
88
117
  if (state.screen === "up_to_date") {
89
- return (_jsxs(FlowPage, { actions: _jsx(FlowButton, { colors: colors, label: translate("common:continue"), onPress: controller.finish }), colors: colors, icon: "check", title: translate("ota:upToDate"), children: [_jsx(BodyText, { colors: colors, children: translate("ota:noUpdatesAvailable") }), state.releaseTransition ? (_jsx(BodyText, { colors: colors, children: translate("ota:updatedToVersion", { version: state.releaseTransition.toVersion }) })) : null, _jsx(ChangelogList, { changelogs: state.changelogs, colors: colors })] }));
118
+ return (_jsxs(FlowPage, { actions: _jsx(FlowButton, { colors: colors, label: translate(state.completedUpdate ? "common:done" : "common:continue"), onPress: controller.finish }), colors: colors, contentAlignment: state.changelogs.length > 0 ? "top" : "center", icon: "check", title: translate(state.completedUpdate ? "ota:updateComplete" : "ota:upToDate"), children: [_jsx(BodyText, { colors: colors, children: translate("ota:noUpdatesAvailable") }), state.releaseTransition ? (_jsx(BodyText, { colors: colors, children: translate("ota:updatedToVersion", { version: state.releaseTransition.toVersion }) })) : null, _jsx(ChangelogList, { changelogs: state.changelogs, colors: colors, title: translate("ota:whatsNew") })] }));
90
119
  }
91
120
  if (state.screen === "update_info_unavailable") {
92
121
  return (_jsx(FlowPage, { actions: _jsx(FlowButton, { colors: colors, label: translate("common:continue"), onPress: controller.finish }), colors: colors, icon: "alert", title: translate("ota:updateInfoUnavailable"), children: _jsx(BodyText, { colors: colors, children: translate("ota:updateInfoUnavailableMessage") }) }));
@@ -111,7 +140,7 @@ function OtaFlowContent({ allowDevSkip, colors, controller, deviceName, superMod
111
140
  return (_jsxs(FlowPage, { colors: colors, icon: "download", title: state.phase === "download" ? "Downloading..." : "Installing...", children: [state.installingApkOnly ? (_jsx(ActivityIndicator, { size: "large", color: colors.foreground })) : (_jsxs(_Fragment, { children: [_jsx(PercentText, { colors: colors, percent: state.progress ?? 0 }), _jsx(View, { style: [styles.progressTrack, { backgroundColor: colors.border }], children: _jsx(View, { style: [styles.progressFill, { backgroundColor: colors.primary, width: `${state.progress ?? 0}%` }] }) })] })), _jsx(BodyText, { colors: colors, children: "Do not disconnect your glasses" }), state.versionChange && state.phase === "install" ? (_jsx(BodyText, { colors: colors, children: translate("ota:downgradeDuration") })) : null] }));
112
141
  }
113
142
  if (state.screen === "restarting") {
114
- return (_jsx(FlowPage, { actions: _jsx(FlowButton, { colors: colors, disabled: state.continueDisabled, label: "Continue", onPress: controller.finish }), colors: colors, icon: "check", title: "Update Installed" }));
143
+ return (_jsxs(FlowPage, { colors: colors, icon: "download", title: translate("ota:restartingGlasses", { deviceName }), children: [_jsx(ActivityIndicator, { size: "large", color: colors.foreground }), _jsx(BodyText, { colors: colors, children: translate("ota:restartingGlassesMessage") }), _jsx(BodyText, { colors: colors, children: translate("ota:restartingGlassesAutomatic") })] }));
115
144
  }
116
145
  if (state.screen === "complete") {
117
146
  const title = state.versionChangeConverged
@@ -124,15 +153,15 @@ function OtaFlowContent({ allowDevSkip, colors, controller, deviceName, superMod
124
153
  : state.versionChange
125
154
  ? translate("ota:versionChangeFirmwarePassCompleteMessage")
126
155
  : "Your glasses are up to date.";
127
- return (_jsxs(FlowPage, { actions: _jsx(FlowButton, { colors: colors, label: state.versionChange && !state.versionChangeConverged ? "Continue" : "Done", onPress: controller.finish }), colors: colors, icon: "check", title: title, children: [_jsx(BodyText, { colors: colors, children: message }), state.releaseTransition ? (_jsx(BodyText, { colors: colors, children: translate("ota:updatedToVersion", { version: state.releaseTransition.toVersion }) })) : null, _jsx(ChangelogList, { changelogs: state.changelogs, colors: colors })] }));
156
+ return (_jsxs(FlowPage, { actions: _jsx(FlowButton, { colors: colors, label: state.versionChange && !state.versionChangeConverged ? "Continue" : "Done", onPress: controller.finish }), colors: colors, contentAlignment: state.changelogs.length > 0 ? "top" : "center", icon: "check", title: title, children: [_jsx(BodyText, { colors: colors, children: message }), state.releaseTransition ? (_jsx(BodyText, { colors: colors, children: translate("ota:updatedToVersion", { version: state.releaseTransition.toVersion }) })) : null, _jsx(ChangelogList, { changelogs: state.changelogs, colors: colors, title: translate("ota:whatsNew") })] }));
128
157
  }
129
158
  if (state.screen === "failed") {
130
159
  return (_jsx(FlowPage, { actions: _jsxs(_Fragment, { children: [_jsx(FlowButton, { colors: colors, label: state.canRetry ? "Retry" : "Done", onPress: state.canRetry ? controller.retryInstall : controller.finish }), state.canOpenWifiSetup ? (_jsx(FlowButton, { colors: colors, label: "Change WiFi", onPress: controller.openWifiSetup, secondary: true })) : null] }), colors: colors, icon: "alert", title: "Update Failed", children: _jsx(BodyText, { colors: colors, children: state.error?.message }) }));
131
160
  }
132
161
  return (_jsxs(FlowPage, { actions: superMode ? (_jsx(FlowButton, { colors: colors, label: "Skip (super)", onPress: controller.discard, secondary: true })) : undefined, colors: colors, icon: "bluetooth", title: "Glasses disconnected", children: [_jsx(BodyText, { colors: colors, children: "Reconnecting..." }), _jsx(ActivityIndicator, { size: "large", color: colors.foreground })] }));
133
162
  }
134
- function FlowPage({ actions, children, colors, icon, title }) {
135
- return (_jsxs(View, { style: styles.page, testID: "mentra-live-ota-flow", children: [_jsxs(View, { style: styles.centerContent, children: [_jsx(FlowIcon, { colors: colors, name: icon }), _jsx(Text, { style: [styles.title, { color: colors.foreground }], children: title }), children] }), actions ? _jsx(View, { style: styles.actions, children: actions }) : _jsx(View, { style: styles.actionSpacer })] }));
163
+ function FlowPage({ actions, children, colors, contentAlignment = "center", icon, title }) {
164
+ return (_jsxs(View, { style: styles.page, testID: "mentra-live-ota-flow", children: [_jsxs(View, { style: [styles.centerContent, contentAlignment === "top" && styles.topContent], children: [_jsx(FlowIcon, { colors: colors, name: icon }), _jsx(Text, { style: [styles.title, { color: colors.foreground }], children: title }), children] }), actions ? _jsx(View, { style: styles.actions, children: actions }) : _jsx(View, { style: styles.actionSpacer })] }));
136
165
  }
137
166
  function BodyText({ children, colors }) {
138
167
  return _jsx(Text, { style: [styles.body, { color: colors.textDim }], children: children });
@@ -140,10 +169,90 @@ function BodyText({ children, colors }) {
140
169
  function PercentText({ colors, percent }) {
141
170
  return _jsxs(Text, { style: [styles.percent, { color: colors.primary }], children: [Math.round(percent), "%"] });
142
171
  }
143
- function ChangelogList({ changelogs, colors, }) {
172
+ function ChangelogMarkdown({ colors, markdown }) {
173
+ const markdownStyles = useMemo(() => ({
174
+ blockquote: {
175
+ borderLeftColor: colors.primary,
176
+ borderLeftWidth: 3,
177
+ marginVertical: 2,
178
+ opacity: 1,
179
+ paddingLeft: 12,
180
+ },
181
+ code: {
182
+ backgroundColor: colors.background,
183
+ borderColor: colors.border,
184
+ borderRadius: 8,
185
+ borderWidth: 1,
186
+ padding: 12,
187
+ },
188
+ codespan: {
189
+ backgroundColor: colors.border,
190
+ color: colors.foreground,
191
+ fontFamily: "monospace",
192
+ fontSize: 13,
193
+ fontStyle: "normal",
194
+ fontWeight: "400",
195
+ },
196
+ em: { color: colors.textDim, fontSize: 14, lineHeight: 20 },
197
+ h1: {
198
+ borderBottomWidth: 0,
199
+ color: colors.foreground,
200
+ fontSize: 18,
201
+ fontWeight: "700",
202
+ lineHeight: 24,
203
+ marginVertical: 0,
204
+ paddingBottom: 0,
205
+ },
206
+ h2: {
207
+ borderBottomWidth: 0,
208
+ color: colors.foreground,
209
+ fontSize: 17,
210
+ fontWeight: "700",
211
+ lineHeight: 23,
212
+ marginVertical: 0,
213
+ paddingBottom: 0,
214
+ },
215
+ h3: { color: colors.foreground, fontSize: 16, fontWeight: "700", lineHeight: 22, marginVertical: 0 },
216
+ h4: { color: colors.foreground, fontSize: 15, fontWeight: "700", lineHeight: 21, marginVertical: 0 },
217
+ h5: { color: colors.foreground, fontSize: 14, fontWeight: "700", lineHeight: 20, marginVertical: 0 },
218
+ h6: { color: colors.textDim, fontSize: 14, fontWeight: "600", lineHeight: 20, marginVertical: 0 },
219
+ hr: { borderBottomColor: colors.border, marginVertical: 2 },
220
+ image: { borderRadius: 8 },
221
+ li: { color: colors.textDim, fontSize: 14, lineHeight: 20 },
222
+ link: {
223
+ color: colors.primary,
224
+ fontSize: 14,
225
+ fontStyle: "normal",
226
+ lineHeight: 20,
227
+ textDecorationLine: "underline",
228
+ },
229
+ paragraph: { paddingVertical: 0 },
230
+ strikethrough: { color: colors.textDim, fontSize: 14, lineHeight: 20 },
231
+ strong: { color: colors.foreground, fontSize: 14, fontWeight: "700", lineHeight: 20 },
232
+ table: { borderColor: colors.border, borderRadius: 8 },
233
+ tableCell: { padding: 8 },
234
+ text: { color: colors.textDim, fontSize: 14, lineHeight: 20 },
235
+ }), [colors]);
236
+ const markdownTheme = useMemo(() => ({
237
+ colors: {
238
+ background: colors.background,
239
+ border: colors.border,
240
+ code: colors.border,
241
+ link: colors.primary,
242
+ text: colors.textDim,
243
+ },
244
+ }), [colors]);
245
+ const elements = useMarkdown(markdown, { colorScheme: "light", styles: markdownStyles, theme: markdownTheme });
246
+ return (_jsx(View, { style: styles.changelogMarkdownContent, testID: "ota-changelog-markdown", children: elements }));
247
+ }
248
+ export function ChangelogList({ changelogs, colors, title, }) {
144
249
  if (changelogs.length === 0)
145
250
  return null;
146
- return (_jsx(ScrollView, { contentContainerStyle: styles.changelogContent, style: styles.changelogList, children: changelogs.map((entry) => (_jsxs(View, { style: styles.changelogEntry, children: [_jsx(Text, { selectable: true, style: [styles.changelogVersion, { color: colors.foreground }], children: entry.version }), _jsx(Text, { selectable: true, style: [styles.changelogMarkdown, { color: colors.textDim }], children: entry.markdown })] }, entry.version))) }));
251
+ return (_jsxs(View, { style: [styles.changelogCard, { borderColor: colors.border }], testID: "ota-changelog-card", children: [_jsx(Text, { style: [styles.changelogTitle, { color: colors.foreground }], children: title }), _jsx(ScrollView, { contentContainerStyle: styles.changelogContent, nestedScrollEnabled: true, showsVerticalScrollIndicator: true, style: styles.changelogList, testID: "ota-changelog-scroll", children: changelogs.map((entry, index) => (_jsxs(View, { style: [
252
+ styles.changelogEntry,
253
+ index > 0 && styles.changelogEntryDivider,
254
+ index > 0 && { borderTopColor: colors.border },
255
+ ], children: [_jsx(Text, { selectable: true, style: [styles.changelogVersion, { color: colors.foreground }], children: entry.version }), _jsx(ChangelogMarkdown, { colors: colors, markdown: entry.markdown })] }, entry.version))) })] }));
147
256
  }
148
257
  function FlowButton({ colors, disabled = false, label, onPress, secondary = false, }) {
149
258
  return (_jsx(Pressable, { accessibilityRole: "button", disabled: disabled, onPress: onPress, style: ({ pressed }) => [
@@ -174,6 +283,7 @@ const styles = StyleSheet.create({
174
283
  },
175
284
  page: { flex: 1, paddingBottom: 24, paddingHorizontal: 24 },
176
285
  centerContent: { alignItems: "center", flex: 1, gap: 16, justifyContent: "center" },
286
+ topContent: { justifyContent: "flex-start", paddingTop: 12 },
177
287
  actionSpacer: { height: 48 },
178
288
  actions: { gap: 12 },
179
289
  icon: { fontSize: 64, fontWeight: "500", lineHeight: 72, textAlign: "center" },
@@ -182,11 +292,23 @@ const styles = StyleSheet.create({
182
292
  percent: { fontSize: 30, fontVariant: ["tabular-nums"], fontWeight: "700" },
183
293
  progressTrack: { borderRadius: 4, height: 8, maxWidth: 420, overflow: "hidden", width: "100%" },
184
294
  progressFill: { borderRadius: 4, height: 8 },
185
- changelogList: { flexShrink: 1, maxHeight: 260, maxWidth: 420, width: "100%" },
186
- changelogContent: { gap: 18, paddingVertical: 4 },
295
+ changelogCard: {
296
+ borderRadius: 16,
297
+ borderWidth: 1,
298
+ flexShrink: 1,
299
+ gap: 12,
300
+ maxHeight: 300,
301
+ maxWidth: 420,
302
+ padding: 16,
303
+ width: "100%",
304
+ },
305
+ changelogTitle: { fontSize: 16, fontWeight: "700" },
306
+ changelogList: { flexShrink: 1, maxHeight: 232, width: "100%" },
307
+ changelogContent: { gap: 20, paddingBottom: 2 },
187
308
  changelogEntry: { gap: 8 },
188
- changelogVersion: { fontSize: 16, fontWeight: "600" },
189
- changelogMarkdown: { fontSize: 14, lineHeight: 20 },
309
+ changelogEntryDivider: { borderTopWidth: StyleSheet.hairlineWidth, paddingTop: 20 },
310
+ changelogVersion: { fontSize: 14, fontWeight: "600" },
311
+ changelogMarkdownContent: { gap: 10 },
190
312
  button: {
191
313
  alignItems: "center",
192
314
  borderRadius: 50,