@elizaos/plugin-facewear 2.0.3-beta.5 → 2.0.3-beta.7

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 (191) hide show
  1. package/dist/actions/display-text.d.ts +4 -0
  2. package/dist/actions/display-text.d.ts.map +1 -0
  3. package/dist/actions/display-text.js +90 -0
  4. package/dist/actions/display-text.js.map +1 -0
  5. package/dist/actions/facewear-connect.d.ts +3 -0
  6. package/dist/actions/facewear-connect.d.ts.map +1 -0
  7. package/dist/actions/facewear-connect.js +70 -0
  8. package/dist/actions/facewear-connect.js.map +1 -0
  9. package/dist/actions/facewear-control.d.ts +4 -0
  10. package/dist/actions/facewear-control.d.ts.map +1 -0
  11. package/dist/actions/facewear-control.js +627 -0
  12. package/dist/actions/facewear-control.js.map +1 -0
  13. package/dist/actions/facewear-debug.d.ts +3 -0
  14. package/dist/actions/facewear-debug.d.ts.map +1 -0
  15. package/dist/actions/facewear-debug.js +62 -0
  16. package/dist/actions/facewear-debug.js.map +1 -0
  17. package/dist/actions/facewear-status.d.ts +4 -0
  18. package/dist/actions/facewear-status.d.ts.map +1 -0
  19. package/dist/actions/facewear-status.js +66 -0
  20. package/dist/actions/facewear-status.js.map +1 -0
  21. package/dist/actions/microphone.d.ts +4 -0
  22. package/dist/actions/microphone.d.ts.map +1 -0
  23. package/dist/actions/microphone.js +63 -0
  24. package/dist/actions/microphone.js.map +1 -0
  25. package/dist/actions/view-actions.d.ts +23 -0
  26. package/dist/actions/view-actions.d.ts.map +1 -0
  27. package/dist/actions/view-actions.js +314 -0
  28. package/dist/actions/view-actions.js.map +1 -0
  29. package/dist/actions/vision-query.d.ts +4 -0
  30. package/dist/actions/vision-query.d.ts.map +1 -0
  31. package/dist/actions/vision-query.js +41 -0
  32. package/dist/actions/vision-query.js.map +1 -0
  33. package/dist/actions/xr-view-actions.d.ts +14 -0
  34. package/dist/actions/xr-view-actions.d.ts.map +1 -0
  35. package/dist/actions/xr-view-actions.js +29 -0
  36. package/dist/actions/xr-view-actions.js.map +1 -0
  37. package/dist/components/FacewearSpatialView.d.ts +50 -0
  38. package/dist/components/FacewearSpatialView.d.ts.map +1 -0
  39. package/dist/components/FacewearSpatialView.js +129 -0
  40. package/dist/components/FacewearSpatialView.js.map +1 -0
  41. package/dist/components/FacewearView.d.ts +17 -0
  42. package/dist/components/FacewearView.d.ts.map +1 -0
  43. package/dist/components/FacewearView.js +88 -0
  44. package/dist/components/FacewearView.js.map +1 -0
  45. package/dist/components/SmartglassesPanelView.d.ts +22 -0
  46. package/dist/components/SmartglassesPanelView.d.ts.map +1 -0
  47. package/dist/components/SmartglassesPanelView.js +140 -0
  48. package/dist/components/SmartglassesPanelView.js.map +1 -0
  49. package/dist/components/SmartglassesSpatialView.d.ts +46 -0
  50. package/dist/components/SmartglassesSpatialView.d.ts.map +1 -0
  51. package/dist/components/SmartglassesSpatialView.js +240 -0
  52. package/dist/components/SmartglassesSpatialView.js.map +1 -0
  53. package/dist/components/facewear-profiles.d.ts +27 -0
  54. package/dist/components/facewear-profiles.d.ts.map +1 -0
  55. package/dist/components/facewear-profiles.js +40 -0
  56. package/dist/components/facewear-profiles.js.map +1 -0
  57. package/dist/devices/apple-vision-pro.d.ts +7 -0
  58. package/dist/devices/apple-vision-pro.d.ts.map +1 -0
  59. package/dist/devices/apple-vision-pro.js +21 -0
  60. package/dist/devices/apple-vision-pro.js.map +1 -0
  61. package/dist/devices/even-realities.d.ts +7 -0
  62. package/dist/devices/even-realities.d.ts.map +1 -0
  63. package/dist/devices/even-realities.js +13 -0
  64. package/dist/devices/even-realities.js.map +1 -0
  65. package/dist/devices/meta-quest.d.ts +5 -0
  66. package/dist/devices/meta-quest.d.ts.map +1 -0
  67. package/dist/devices/meta-quest.js +21 -0
  68. package/dist/devices/meta-quest.js.map +1 -0
  69. package/dist/devices/registry.d.ts +19 -0
  70. package/dist/devices/registry.d.ts.map +1 -0
  71. package/dist/devices/registry.js +96 -0
  72. package/dist/devices/registry.js.map +1 -0
  73. package/dist/devices/xreal.d.ts +7 -0
  74. package/dist/devices/xreal.d.ts.map +1 -0
  75. package/dist/devices/xreal.js +19 -0
  76. package/dist/devices/xreal.js.map +1 -0
  77. package/dist/index.d.ts +28 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +260 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/protocol/smartglasses.d.ts +306 -0
  82. package/dist/protocol/smartglasses.d.ts.map +1 -0
  83. package/dist/protocol/smartglasses.js +1485 -0
  84. package/dist/protocol/smartglasses.js.map +1 -0
  85. package/dist/protocol/xr.d.ts +137 -0
  86. package/dist/protocol/xr.d.ts.map +1 -0
  87. package/dist/protocol/xr.js +18 -0
  88. package/dist/protocol/xr.js.map +1 -0
  89. package/dist/providers/facewear-context.d.ts +3 -0
  90. package/dist/providers/facewear-context.d.ts.map +1 -0
  91. package/dist/providers/facewear-context.js +59 -0
  92. package/dist/providers/facewear-context.js.map +1 -0
  93. package/dist/providers/smartglasses-status.d.ts +3 -0
  94. package/dist/providers/smartglasses-status.d.ts.map +1 -0
  95. package/dist/providers/smartglasses-status.js +33 -0
  96. package/dist/providers/smartglasses-status.js.map +1 -0
  97. package/dist/register-terminal-view.d.ts +21 -0
  98. package/dist/register-terminal-view.d.ts.map +1 -0
  99. package/dist/register-terminal-view.js +70 -0
  100. package/dist/register-terminal-view.js.map +1 -0
  101. package/dist/register.d.ts +8 -0
  102. package/dist/register.d.ts.map +1 -0
  103. package/dist/register.js +116 -0
  104. package/dist/register.js.map +1 -0
  105. package/dist/routes/connect.d.ts +3 -0
  106. package/dist/routes/connect.d.ts.map +1 -0
  107. package/dist/routes/connect.js +86 -0
  108. package/dist/routes/connect.js.map +1 -0
  109. package/dist/routes/device-config.d.ts +5 -0
  110. package/dist/routes/device-config.d.ts.map +1 -0
  111. package/dist/routes/device-config.js +56 -0
  112. package/dist/routes/device-config.js.map +1 -0
  113. package/dist/routes/simulator-route.d.ts +8 -0
  114. package/dist/routes/simulator-route.d.ts.map +1 -0
  115. package/dist/routes/simulator-route.js +32 -0
  116. package/dist/routes/simulator-route.js.map +1 -0
  117. package/dist/routes/status.d.ts +3 -0
  118. package/dist/routes/status.d.ts.map +1 -0
  119. package/dist/routes/status.js +34 -0
  120. package/dist/routes/status.js.map +1 -0
  121. package/dist/routes/view-host.d.ts +24 -0
  122. package/dist/routes/view-host.d.ts.map +1 -0
  123. package/dist/routes/view-host.js +339 -0
  124. package/dist/routes/view-host.js.map +1 -0
  125. package/dist/routes/views.d.ts +8 -0
  126. package/dist/routes/views.d.ts.map +1 -0
  127. package/dist/routes/views.js +31 -0
  128. package/dist/routes/views.js.map +1 -0
  129. package/dist/services/audio-pipeline.d.ts +20 -0
  130. package/dist/services/audio-pipeline.d.ts.map +1 -0
  131. package/dist/services/audio-pipeline.js +87 -0
  132. package/dist/services/audio-pipeline.js.map +1 -0
  133. package/dist/services/facewear-service.d.ts +26 -0
  134. package/dist/services/facewear-service.d.ts.map +1 -0
  135. package/dist/services/facewear-service.js +45 -0
  136. package/dist/services/facewear-service.js.map +1 -0
  137. package/dist/services/smartglasses-service.d.ts +244 -0
  138. package/dist/services/smartglasses-service.d.ts.map +1 -0
  139. package/dist/services/smartglasses-service.js +821 -0
  140. package/dist/services/smartglasses-service.js.map +1 -0
  141. package/dist/services/vision-pipeline.d.ts +16 -0
  142. package/dist/services/vision-pipeline.d.ts.map +1 -0
  143. package/dist/services/vision-pipeline.js +39 -0
  144. package/dist/services/vision-pipeline.js.map +1 -0
  145. package/dist/services/xr-session-service.d.ts +54 -0
  146. package/dist/services/xr-session-service.d.ts.map +1 -0
  147. package/dist/services/xr-session-service.js +345 -0
  148. package/dist/services/xr-session-service.js.map +1 -0
  149. package/dist/status-format.d.ts +15 -0
  150. package/dist/status-format.d.ts.map +1 -0
  151. package/dist/status-format.js +89 -0
  152. package/dist/status-format.js.map +1 -0
  153. package/dist/transport/even-bridge.d.ts +69 -0
  154. package/dist/transport/even-bridge.d.ts.map +1 -0
  155. package/dist/transport/even-bridge.js +510 -0
  156. package/dist/transport/even-bridge.js.map +1 -0
  157. package/dist/transport/mock.d.ts +42 -0
  158. package/dist/transport/mock.d.ts.map +1 -0
  159. package/dist/transport/mock.js +124 -0
  160. package/dist/transport/mock.js.map +1 -0
  161. package/dist/transport/noble.d.ts +62 -0
  162. package/dist/transport/noble.d.ts.map +1 -0
  163. package/dist/transport/noble.js +256 -0
  164. package/dist/transport/noble.js.map +1 -0
  165. package/dist/transport/types.d.ts +36 -0
  166. package/dist/transport/types.d.ts.map +1 -0
  167. package/dist/transport/types.js +1 -0
  168. package/dist/transport/types.js.map +1 -0
  169. package/dist/transport/web-bluetooth.d.ts +58 -0
  170. package/dist/transport/web-bluetooth.d.ts.map +1 -0
  171. package/dist/transport/web-bluetooth.js +164 -0
  172. package/dist/transport/web-bluetooth.js.map +1 -0
  173. package/dist/ui/FacewearAppView.d.ts +4 -0
  174. package/dist/ui/FacewearAppView.d.ts.map +1 -0
  175. package/dist/ui/FacewearAppView.js +257 -0
  176. package/dist/ui/FacewearAppView.js.map +1 -0
  177. package/dist/ui/SmartglassesView.d.ts +10 -0
  178. package/dist/ui/SmartglassesView.d.ts.map +1 -0
  179. package/dist/ui/SmartglassesView.helpers.d.ts +104 -0
  180. package/dist/ui/SmartglassesView.helpers.d.ts.map +1 -0
  181. package/dist/ui/SmartglassesView.helpers.js +261 -0
  182. package/dist/ui/SmartglassesView.helpers.js.map +1 -0
  183. package/dist/ui/SmartglassesView.js +1189 -0
  184. package/dist/ui/SmartglassesView.js.map +1 -0
  185. package/dist/ui/facewear-view-bundle.d.ts +5 -0
  186. package/dist/ui/facewear-view-bundle.d.ts.map +1 -0
  187. package/dist/ui/facewear-view-bundle.js +17 -0
  188. package/dist/ui/facewear-view-bundle.js.map +1 -0
  189. package/dist/views/bundle.js +2950 -0
  190. package/dist/views/bundle.js.map +1 -0
  191. package/package.json +5 -5
@@ -0,0 +1,261 @@
1
+ import {
2
+ encodeTextPackets,
3
+ G1AiStatus,
4
+ G1ScreenAction,
5
+ G1TextStatus,
6
+ paginateDisplayText
7
+ } from "../protocol/smartglasses.js";
8
+ function isMicEnableTap(label) {
9
+ return label === "single_tap" || label === "long_press";
10
+ }
11
+ function isMicDisableTap(label) {
12
+ return label === "double_tap" || label === "stop_ai_recording";
13
+ }
14
+ function reportTimeMs(value) {
15
+ const ms = Date.parse(value);
16
+ return Number.isFinite(ms) ? ms : null;
17
+ }
18
+ function reportHappenedAfter(later, earlier) {
19
+ const laterMs = reportTimeMs(later.at);
20
+ const earlierMs = reportTimeMs(earlier.at);
21
+ return laterMs !== null && earlierMs !== null ? laterMs >= earlierMs : false;
22
+ }
23
+ function hasTapDrivenViewMicWrite(events, writes, mode) {
24
+ const isTap = mode === "enable" ? isMicEnableTap : isMicDisableTap;
25
+ const expectedHex = mode === "enable" ? "0e01" : "0e00";
26
+ const tapEvents = events.filter((event) => isTap(event.detail));
27
+ const micWrites = writes.filter(
28
+ (write) => write.side === "right" && write.command === "open-mic" && write.hex.startsWith(expectedHex)
29
+ );
30
+ return tapEvents.some(
31
+ (event) => micWrites.some((write) => reportHappenedAfter(write, event))
32
+ );
33
+ }
34
+ function isCradleOrChargingState(physicalState, batteryState) {
35
+ return physicalState === "cradle_open" || physicalState === "cradle_closed" || physicalState === "charged_in_cradle" || batteryState === "glasses_fully_charged" || batteryState === "cradle_charging_cable_changed" || batteryState === "cradle_fully_charged";
36
+ }
37
+ function headsetValidationBlocker(physicalState, batteryState) {
38
+ if (physicalState === "wearing") return null;
39
+ const stateText = [physicalState, batteryState].filter(Boolean).join(" / ") || "no wearing state observed";
40
+ if (isCradleOrChargingState(physicalState, batteryState)) {
41
+ return `Glasses are still reporting ${stateText}. Remove them from the charging base and wear them before tap or microphone validation.`;
42
+ }
43
+ return `Tap and microphone validation requires a wearing state; current state is ${stateText}.`;
44
+ }
45
+ function missingViewEvidence(tests, lenses, physicalState, batteryState, events = [], writes = []) {
46
+ const hasTapDrivenEnableWrite = hasTapDrivenViewMicWrite(
47
+ events,
48
+ writes,
49
+ "enable"
50
+ );
51
+ const hasTapDrivenDisableWrite = hasTapDrivenViewMicWrite(
52
+ events,
53
+ writes,
54
+ "disable"
55
+ );
56
+ const missing = [
57
+ lenses.left !== "connected" && "leftLensConnected",
58
+ lenses.right !== "connected" && "rightLensConnected",
59
+ physicalState !== "wearing" && "wearingStateObserved",
60
+ isCradleOrChargingState(physicalState, batteryState) && "headsetInCradle",
61
+ !tests.init && "connectionReadySent",
62
+ !tests.display && "displayPacketsSent",
63
+ !tests.serial && "serialRequested",
64
+ !tests.serialObserved && "serialObserved",
65
+ !tests.settings && "settingsSent",
66
+ !hasTapDrivenEnableWrite && "rightMicEnableWrite",
67
+ !hasTapDrivenDisableWrite && "rightMicDisableWrite",
68
+ !tests.tapMicEnable && "tapMicEnable",
69
+ !tests.tapMicDisable && "tapMicDisable",
70
+ !tests.audio && "rightOrBridgeAudio"
71
+ ].filter((value) => typeof value === "string");
72
+ return [...new Set(missing)];
73
+ }
74
+ function viewScanDiagnosis(lenses) {
75
+ if (lenses.left === "connected" && lenses.right === "connected") {
76
+ return "whole_headset_seen";
77
+ }
78
+ if (lenses.left === "failed" || lenses.right === "failed") {
79
+ return "pairing_failed";
80
+ }
81
+ if (lenses.left === "connected") return "right_lens_missing";
82
+ if (lenses.right === "connected") return "left_lens_missing";
83
+ return "not_scanned";
84
+ }
85
+ function viewPhysicalBlocker(tests, lenses, physicalState, batteryState, events = [], writes = []) {
86
+ const wholeHeadset = lenses.left === "connected" && lenses.right === "connected";
87
+ if (!wholeHeadset && (lenses.left === "connected" || lenses.right === "connected")) {
88
+ return "partial_headset";
89
+ }
90
+ if (!wholeHeadset) return "not_connected";
91
+ if (isCradleOrChargingState(physicalState, batteryState)) {
92
+ return "in_charging_base";
93
+ }
94
+ if (physicalState !== "wearing") return "wearing_state_missing";
95
+ return missingViewEvidence(
96
+ tests,
97
+ lenses,
98
+ physicalState,
99
+ batteryState,
100
+ events,
101
+ writes
102
+ ).length ? "evidence_missing" : null;
103
+ }
104
+ function viewSetupHint(blocker, physicalState, batteryState) {
105
+ if (blocker === "not_connected") {
106
+ return "Connect both left and right lenses as one headset before running validation.";
107
+ }
108
+ if (blocker === "partial_headset") {
109
+ return "Reconnect the whole headset so both left and right lenses are present.";
110
+ }
111
+ if (blocker === "in_charging_base" || blocker === "wearing_state_missing") {
112
+ return headsetValidationBlocker(physicalState, batteryState);
113
+ }
114
+ if (blocker === "evidence_missing") {
115
+ return "Run check, then guided validation to capture display, settings, side taps, mic writes, and audio.";
116
+ }
117
+ return null;
118
+ }
119
+ function viewNextAction(blocker) {
120
+ if (blocker === "not_connected") return "Connect Headset";
121
+ if (blocker === "partial_headset") return "Reconnect the missing lens";
122
+ if (blocker === "in_charging_base") {
123
+ return "Remove the glasses from the charging base and wear them";
124
+ }
125
+ if (blocker === "wearing_state_missing") {
126
+ return "Wear the glasses until wearing state appears";
127
+ }
128
+ if (blocker === "evidence_missing") return "Run Check and Guided Validation";
129
+ return null;
130
+ }
131
+ function viewCommandName(data) {
132
+ switch (data[0]) {
133
+ case 1:
134
+ return "brightness";
135
+ case 14:
136
+ return "open-mic";
137
+ case 28:
138
+ return "silent-mode";
139
+ case 44:
140
+ return "battery-status";
141
+ case 52:
142
+ return "get-serial";
143
+ case 77:
144
+ return "init";
145
+ case 78:
146
+ return "display-result";
147
+ case 244:
148
+ return "right-init";
149
+ default:
150
+ return data.length > 0 ? `0x${data[0].toString(16).padStart(2, "0")}` : "empty";
151
+ }
152
+ }
153
+ function withViewScreenStatus(page, screenStatus) {
154
+ return { ...page, screenStatus };
155
+ }
156
+ function viewStreamingStatus(mode, pageIndex) {
157
+ if (mode === "text") return G1TextStatus.TextShow | G1ScreenAction.NewContent;
158
+ return pageIndex === 0 ? G1AiStatus.Displaying | G1ScreenAction.NewContent : G1AiStatus.Displaying;
159
+ }
160
+ function buildViewDisplayPackets(text, options = {}) {
161
+ const mode = options.mode ?? "ai";
162
+ let seq = options.startSeq ?? 0;
163
+ const packets = [];
164
+ const pages = paginateDisplayText(text);
165
+ for (const [pageIndex, page] of pages.entries()) {
166
+ packets.push(
167
+ ...encodeTextPackets(
168
+ withViewScreenStatus(page, viewStreamingStatus(mode, pageIndex)),
169
+ seq
170
+ )
171
+ );
172
+ seq = seq + 1 & 255;
173
+ }
174
+ if (mode !== "text" && options.includeCompletion !== false) {
175
+ const lastPage = pages.at(-1);
176
+ if (lastPage) {
177
+ packets.push(
178
+ ...encodeTextPackets(
179
+ withViewScreenStatus(lastPage, G1AiStatus.DisplayComplete),
180
+ seq
181
+ )
182
+ );
183
+ seq = seq + 1 & 255;
184
+ }
185
+ }
186
+ return { packets, pages: pages.length, nextSeq: seq };
187
+ }
188
+ function parseWifiNetworks(result) {
189
+ if (!result || typeof result !== "object") return [];
190
+ const value = result;
191
+ const networks = value.networks ?? value.wifiNetworks ?? value.accessPoints ?? value.networks_neo ?? value.results;
192
+ if (!Array.isArray(networks)) return [];
193
+ return networks.map((network) => {
194
+ if (typeof network === "string") return network;
195
+ if (network && typeof network === "object") {
196
+ const record = network;
197
+ return String(record.ssid ?? record.SSID ?? record.name ?? "");
198
+ }
199
+ return "";
200
+ }).map((network) => network.trim()).filter((network) => network.length > 0);
201
+ }
202
+ function formatWifiStatus(result, fallback = "Wi-Fi status requested") {
203
+ if (!result || typeof result !== "object") return fallback;
204
+ const value = result;
205
+ const explicitStatus = value.status ?? value.state ?? value.message;
206
+ if (typeof explicitStatus === "string" && explicitStatus.trim()) {
207
+ return explicitStatus.trim();
208
+ }
209
+ const connected = value.connected ?? value.wifiConnected;
210
+ const ssid = value.ssid ?? value.wifiSsid ?? value.SSID;
211
+ const localIp = value.localIp ?? value.wifiLocalIp ?? value.ipAddress;
212
+ if (connected === true) {
213
+ return `Connected to ${String(ssid ?? "Wi-Fi")}${localIp ? ` at ${String(localIp)}` : ""}`;
214
+ }
215
+ if (connected === false) return "Wi-Fi disconnected";
216
+ return fallback;
217
+ }
218
+ async function callWifiBridge(bridge, command, payload) {
219
+ if (command === "request_wifi_scan" && bridge.requestWifiScan) {
220
+ return bridge.requestWifiScan();
221
+ }
222
+ if (command === "request_wifi_status" && bridge.requestWifiStatus) {
223
+ return bridge.requestWifiStatus();
224
+ }
225
+ if (command === "request_wifi_setup" && bridge.requestWifiSetup) {
226
+ return bridge.requestWifiSetup(String(payload?.reason ?? ""));
227
+ }
228
+ if (command === "set_wifi_credentials") {
229
+ const ssid = String(payload?.ssid ?? "");
230
+ const password = String(payload?.password ?? "");
231
+ if (bridge.setWifiCredentials) {
232
+ return bridge.setWifiCredentials(ssid, password);
233
+ }
234
+ if (bridge.sendWifiCredentials) {
235
+ return bridge.sendWifiCredentials(ssid, password);
236
+ }
237
+ }
238
+ if (bridge.rawBridge?.callEvenApp) {
239
+ return bridge.rawBridge.callEvenApp(command, payload);
240
+ }
241
+ throw new Error(
242
+ `Native smartglasses bridge does not support Wi-Fi command: ${command}`
243
+ );
244
+ }
245
+ export {
246
+ buildViewDisplayPackets,
247
+ callWifiBridge,
248
+ formatWifiStatus,
249
+ headsetValidationBlocker,
250
+ isCradleOrChargingState,
251
+ isMicDisableTap,
252
+ isMicEnableTap,
253
+ missingViewEvidence,
254
+ parseWifiNetworks,
255
+ viewCommandName,
256
+ viewNextAction,
257
+ viewPhysicalBlocker,
258
+ viewScanDiagnosis,
259
+ viewSetupHint
260
+ };
261
+ //# sourceMappingURL=SmartglassesView.helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ui/SmartglassesView.helpers.ts"],"sourcesContent":["// Pure smartglasses report/diagnostics helpers split out of SmartglassesView.tsx\n// so that file exports only the React component and stays Fast-Refresh-compatible\n// (Vite full-reloads a component file that also exports plain functions/types).\n// SmartglassesView.tsx and the report test both import from here.\n\nimport {\n type DisplayPage,\n encodeTextPackets,\n G1AiStatus,\n G1ScreenAction,\n G1TextStatus,\n type GlassSide,\n paginateDisplayText,\n type SmartglassesAudioEncoding,\n} from \"../protocol/smartglasses.js\";\n\nexport type LensState = \"idle\" | \"prompting\" | \"connected\" | \"failed\";\nexport type ViewScanDiagnosis =\n | \"not_scanned\"\n | \"left_lens_missing\"\n | \"right_lens_missing\"\n | \"whole_headset_seen\"\n | \"pairing_failed\";\nexport type ViewPhysicalBlocker =\n | \"not_connected\"\n | \"partial_headset\"\n | \"in_charging_base\"\n | \"wearing_state_missing\"\n | \"evidence_missing\"\n | null;\n\nexport interface ReportEvent {\n at: string;\n type: string;\n detail: string;\n}\n\nexport interface ReportWrite {\n at: string;\n side: GlassSide | \"both\";\n command: string;\n bytes: number;\n hex: string;\n}\n\nexport interface ReportAudio {\n at: string;\n side: GlassSide;\n sampleRate: number;\n encoding: SmartglassesAudioEncoding | null;\n sequence?: number;\n bytes: number;\n}\n\nexport interface HardwareReport {\n ok: boolean;\n generatedAt: string;\n transport: string | null;\n connected: boolean;\n lenses: Record<GlassSide, LensState>;\n scanDiagnosis: ViewScanDiagnosis;\n physicalBlocker: ViewPhysicalBlocker;\n setupHint: string | null;\n nextAction: string | null;\n serialNumber: string | null;\n tests: Record<string, boolean>;\n missingEvidence: string[];\n events: ReportEvent[];\n writes: ReportWrite[];\n audio: ReportAudio[];\n wifi: {\n available: boolean;\n status: string;\n networks: string[];\n };\n headsetState: {\n physical: string | null;\n battery: string | null;\n batteryLevels: Partial<Record<GlassSide, number>>;\n device: string | null;\n };\n}\n\ntype BridgeResult = unknown;\ntype BridgeSubscription =\n | undefined\n | (() => void)\n | { unsubscribe?: () => void; off?: () => void; remove?: () => void };\n\nexport type SmartglassesBridge = {\n requestWifiScan?: () => Promise<BridgeResult> | BridgeResult;\n requestWifiStatus?: () => Promise<BridgeResult> | BridgeResult;\n requestWifiSetup?: (reason?: string) => Promise<BridgeResult> | BridgeResult;\n setWifiCredentials?: (\n ssid: string,\n password: string,\n ) => Promise<BridgeResult> | BridgeResult;\n sendWifiCredentials?: (\n ssid: string,\n password: string,\n ) => Promise<BridgeResult> | BridgeResult;\n audioControl?: (enabled: boolean) => Promise<BridgeResult> | BridgeResult;\n clearDisplay?: () => Promise<BridgeResult> | BridgeResult;\n createStartUpPageContainer?: (\n container: Record<string, unknown>,\n ) => Promise<BridgeResult> | BridgeResult;\n displayText?: (\n params: Record<string, unknown>,\n ) => Promise<BridgeResult> | BridgeResult;\n onEvent?: (callback: (event: unknown) => void) => BridgeSubscription;\n onEvenHubEvent?: (callback: (event: unknown) => void) => BridgeSubscription;\n rebuildPageContainer?: (\n container: Record<string, unknown>,\n ) => Promise<BridgeResult> | BridgeResult;\n sendStartUpPage?: (\n container: unknown,\n ) => Promise<BridgeResult> | BridgeResult;\n setMicState?: (\n sendPcmData: boolean,\n sendTranscript: boolean,\n bypassVad: boolean,\n ) => Promise<BridgeResult> | BridgeResult;\n write?: (\n side: GlassSide,\n data: Uint8Array,\n ) => Promise<BridgeResult> | BridgeResult;\n send?: (\n side: GlassSide,\n data: Uint8Array,\n ) => Promise<BridgeResult> | BridgeResult;\n rawBridge?: {\n audioControl?: (enabled: boolean) => Promise<BridgeResult> | BridgeResult;\n callEvenApp?: (\n name: string,\n payload?: Record<string, unknown>,\n ) => Promise<BridgeResult> | BridgeResult;\n };\n};\n\nexport function isMicEnableTap(label?: string | null): boolean {\n return label === \"single_tap\" || label === \"long_press\";\n}\n\nexport function isMicDisableTap(label?: string | null): boolean {\n return label === \"double_tap\" || label === \"stop_ai_recording\";\n}\n\nfunction reportTimeMs(value: string): number | null {\n const ms = Date.parse(value);\n return Number.isFinite(ms) ? ms : null;\n}\n\nfunction reportHappenedAfter(\n later: { at: string },\n earlier: { at: string },\n): boolean {\n const laterMs = reportTimeMs(later.at);\n const earlierMs = reportTimeMs(earlier.at);\n return laterMs !== null && earlierMs !== null ? laterMs >= earlierMs : false;\n}\n\nfunction hasTapDrivenViewMicWrite(\n events: ReportEvent[],\n writes: ReportWrite[],\n mode: \"enable\" | \"disable\",\n): boolean {\n const isTap = mode === \"enable\" ? isMicEnableTap : isMicDisableTap;\n const expectedHex = mode === \"enable\" ? \"0e01\" : \"0e00\";\n const tapEvents = events.filter((event) => isTap(event.detail));\n const micWrites = writes.filter(\n (write) =>\n write.side === \"right\" &&\n write.command === \"open-mic\" &&\n write.hex.startsWith(expectedHex),\n );\n return tapEvents.some((event) =>\n micWrites.some((write) => reportHappenedAfter(write, event)),\n );\n}\n\nexport function isCradleOrChargingState(\n physicalState: string | null,\n batteryState: string | null,\n): boolean {\n return (\n physicalState === \"cradle_open\" ||\n physicalState === \"cradle_closed\" ||\n physicalState === \"charged_in_cradle\" ||\n batteryState === \"glasses_fully_charged\" ||\n batteryState === \"cradle_charging_cable_changed\" ||\n batteryState === \"cradle_fully_charged\"\n );\n}\n\nexport function headsetValidationBlocker(\n physicalState: string | null,\n batteryState: string | null,\n): string | null {\n if (physicalState === \"wearing\") return null;\n const stateText =\n [physicalState, batteryState].filter(Boolean).join(\" / \") ||\n \"no wearing state observed\";\n if (isCradleOrChargingState(physicalState, batteryState)) {\n return `Glasses are still reporting ${stateText}. Remove them from the charging base and wear them before tap or microphone validation.`;\n }\n return `Tap and microphone validation requires a wearing state; current state is ${stateText}.`;\n}\n\nexport function missingViewEvidence(\n tests: Record<string, boolean>,\n lenses: Record<GlassSide, LensState>,\n physicalState: string | null,\n batteryState: string | null,\n events: ReportEvent[] = [],\n writes: ReportWrite[] = [],\n): string[] {\n const hasTapDrivenEnableWrite = hasTapDrivenViewMicWrite(\n events,\n writes,\n \"enable\",\n );\n const hasTapDrivenDisableWrite = hasTapDrivenViewMicWrite(\n events,\n writes,\n \"disable\",\n );\n const missing = [\n lenses.left !== \"connected\" && \"leftLensConnected\",\n lenses.right !== \"connected\" && \"rightLensConnected\",\n physicalState !== \"wearing\" && \"wearingStateObserved\",\n isCradleOrChargingState(physicalState, batteryState) && \"headsetInCradle\",\n !tests.init && \"connectionReadySent\",\n !tests.display && \"displayPacketsSent\",\n !tests.serial && \"serialRequested\",\n !tests.serialObserved && \"serialObserved\",\n !tests.settings && \"settingsSent\",\n !hasTapDrivenEnableWrite && \"rightMicEnableWrite\",\n !hasTapDrivenDisableWrite && \"rightMicDisableWrite\",\n !tests.tapMicEnable && \"tapMicEnable\",\n !tests.tapMicDisable && \"tapMicDisable\",\n !tests.audio && \"rightOrBridgeAudio\",\n ].filter((value): value is string => typeof value === \"string\");\n return [...new Set(missing)];\n}\n\nexport function viewScanDiagnosis(\n lenses: Record<GlassSide, LensState>,\n): ViewScanDiagnosis {\n if (lenses.left === \"connected\" && lenses.right === \"connected\") {\n return \"whole_headset_seen\";\n }\n if (lenses.left === \"failed\" || lenses.right === \"failed\") {\n return \"pairing_failed\";\n }\n if (lenses.left === \"connected\") return \"right_lens_missing\";\n if (lenses.right === \"connected\") return \"left_lens_missing\";\n return \"not_scanned\";\n}\n\nexport function viewPhysicalBlocker(\n tests: Record<string, boolean>,\n lenses: Record<GlassSide, LensState>,\n physicalState: string | null,\n batteryState: string | null,\n events: ReportEvent[] = [],\n writes: ReportWrite[] = [],\n): ViewPhysicalBlocker {\n const wholeHeadset =\n lenses.left === \"connected\" && lenses.right === \"connected\";\n if (\n !wholeHeadset &&\n (lenses.left === \"connected\" || lenses.right === \"connected\")\n ) {\n return \"partial_headset\";\n }\n if (!wholeHeadset) return \"not_connected\";\n if (isCradleOrChargingState(physicalState, batteryState)) {\n return \"in_charging_base\";\n }\n if (physicalState !== \"wearing\") return \"wearing_state_missing\";\n return missingViewEvidence(\n tests,\n lenses,\n physicalState,\n batteryState,\n events,\n writes,\n ).length\n ? \"evidence_missing\"\n : null;\n}\n\nexport function viewSetupHint(\n blocker: ViewPhysicalBlocker,\n physicalState: string | null,\n batteryState: string | null,\n): string | null {\n if (blocker === \"not_connected\") {\n return \"Connect both left and right lenses as one headset before running validation.\";\n }\n if (blocker === \"partial_headset\") {\n return \"Reconnect the whole headset so both left and right lenses are present.\";\n }\n if (blocker === \"in_charging_base\" || blocker === \"wearing_state_missing\") {\n return headsetValidationBlocker(physicalState, batteryState);\n }\n if (blocker === \"evidence_missing\") {\n return \"Run check, then guided validation to capture display, settings, side taps, mic writes, and audio.\";\n }\n return null;\n}\n\nexport function viewNextAction(blocker: ViewPhysicalBlocker): string | null {\n if (blocker === \"not_connected\") return \"Connect Headset\";\n if (blocker === \"partial_headset\") return \"Reconnect the missing lens\";\n if (blocker === \"in_charging_base\") {\n return \"Remove the glasses from the charging base and wear them\";\n }\n if (blocker === \"wearing_state_missing\") {\n return \"Wear the glasses until wearing state appears\";\n }\n if (blocker === \"evidence_missing\") return \"Run Check and Guided Validation\";\n return null;\n}\n\nexport function viewCommandName(data: Uint8Array): string {\n switch (data[0]) {\n case 0x01:\n return \"brightness\";\n case 0x0e:\n return \"open-mic\";\n case 0x1c:\n return \"silent-mode\";\n case 0x2c:\n return \"battery-status\";\n case 0x34:\n return \"get-serial\";\n case 0x4d:\n return \"init\";\n case 0x4e:\n return \"display-result\";\n case 0xf4:\n return \"right-init\";\n default:\n return data.length > 0\n ? `0x${data[0].toString(16).padStart(2, \"0\")}`\n : \"empty\";\n }\n}\n\nfunction withViewScreenStatus(\n page: DisplayPage,\n screenStatus: number,\n): DisplayPage {\n return { ...page, screenStatus };\n}\n\nfunction viewStreamingStatus(mode: \"ai\" | \"text\", pageIndex: number): number {\n if (mode === \"text\") return G1TextStatus.TextShow | G1ScreenAction.NewContent;\n return pageIndex === 0\n ? G1AiStatus.Displaying | G1ScreenAction.NewContent\n : G1AiStatus.Displaying;\n}\n\nexport function buildViewDisplayPackets(\n text: string,\n options: {\n startSeq?: number;\n mode?: \"ai\" | \"text\";\n includeCompletion?: boolean;\n } = {},\n): { packets: Uint8Array[]; pages: number; nextSeq: number } {\n const mode = options.mode ?? \"ai\";\n let seq = options.startSeq ?? 0;\n const packets: Uint8Array[] = [];\n const pages = paginateDisplayText(text);\n for (const [pageIndex, page] of pages.entries()) {\n packets.push(\n ...encodeTextPackets(\n withViewScreenStatus(page, viewStreamingStatus(mode, pageIndex)),\n seq,\n ),\n );\n seq = (seq + 1) & 0xff;\n }\n if (mode !== \"text\" && options.includeCompletion !== false) {\n const lastPage = pages.at(-1);\n if (lastPage) {\n packets.push(\n ...encodeTextPackets(\n withViewScreenStatus(lastPage, G1AiStatus.DisplayComplete),\n seq,\n ),\n );\n seq = (seq + 1) & 0xff;\n }\n }\n return { packets, pages: pages.length, nextSeq: seq };\n}\n\nexport function parseWifiNetworks(result: unknown): string[] {\n if (!result || typeof result !== \"object\") return [];\n const value = result as Record<string, unknown>;\n const networks =\n value.networks ??\n value.wifiNetworks ??\n value.accessPoints ??\n value.networks_neo ??\n value.results;\n if (!Array.isArray(networks)) return [];\n return networks\n .map((network) => {\n if (typeof network === \"string\") return network;\n if (network && typeof network === \"object\") {\n const record = network as Record<string, unknown>;\n return String(record.ssid ?? record.SSID ?? record.name ?? \"\");\n }\n return \"\";\n })\n .map((network) => network.trim())\n .filter((network) => network.length > 0);\n}\n\nexport function formatWifiStatus(\n result: unknown,\n fallback = \"Wi-Fi status requested\",\n): string {\n if (!result || typeof result !== \"object\") return fallback;\n const value = result as Record<string, unknown>;\n const explicitStatus = value.status ?? value.state ?? value.message;\n if (typeof explicitStatus === \"string\" && explicitStatus.trim()) {\n return explicitStatus.trim();\n }\n const connected = value.connected ?? value.wifiConnected;\n const ssid = value.ssid ?? value.wifiSsid ?? value.SSID;\n const localIp = value.localIp ?? value.wifiLocalIp ?? value.ipAddress;\n if (connected === true) {\n return `Connected to ${String(ssid ?? \"Wi-Fi\")}${\n localIp ? ` at ${String(localIp)}` : \"\"\n }`;\n }\n if (connected === false) return \"Wi-Fi disconnected\";\n return fallback;\n}\n\nexport async function callWifiBridge(\n bridge: SmartglassesBridge,\n command: string,\n payload?: Record<string, unknown>,\n): Promise<unknown> {\n if (command === \"request_wifi_scan\" && bridge.requestWifiScan) {\n return bridge.requestWifiScan();\n }\n if (command === \"request_wifi_status\" && bridge.requestWifiStatus) {\n return bridge.requestWifiStatus();\n }\n if (command === \"request_wifi_setup\" && bridge.requestWifiSetup) {\n return bridge.requestWifiSetup(String(payload?.reason ?? \"\"));\n }\n if (command === \"set_wifi_credentials\") {\n const ssid = String(payload?.ssid ?? \"\");\n const password = String(payload?.password ?? \"\");\n if (bridge.setWifiCredentials) {\n return bridge.setWifiCredentials(ssid, password);\n }\n if (bridge.sendWifiCredentials) {\n return bridge.sendWifiCredentials(ssid, password);\n }\n }\n if (bridge.rawBridge?.callEvenApp) {\n return bridge.rawBridge.callEvenApp(command, payload);\n }\n throw new Error(\n `Native smartglasses bridge does not support Wi-Fi command: ${command}`,\n );\n}\n"],"mappings":"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","names":[]}