@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.
- package/dist/actions/display-text.d.ts +4 -0
- package/dist/actions/display-text.d.ts.map +1 -0
- package/dist/actions/display-text.js +90 -0
- package/dist/actions/display-text.js.map +1 -0
- package/dist/actions/facewear-connect.d.ts +3 -0
- package/dist/actions/facewear-connect.d.ts.map +1 -0
- package/dist/actions/facewear-connect.js +70 -0
- package/dist/actions/facewear-connect.js.map +1 -0
- package/dist/actions/facewear-control.d.ts +4 -0
- package/dist/actions/facewear-control.d.ts.map +1 -0
- package/dist/actions/facewear-control.js +627 -0
- package/dist/actions/facewear-control.js.map +1 -0
- package/dist/actions/facewear-debug.d.ts +3 -0
- package/dist/actions/facewear-debug.d.ts.map +1 -0
- package/dist/actions/facewear-debug.js +62 -0
- package/dist/actions/facewear-debug.js.map +1 -0
- package/dist/actions/facewear-status.d.ts +4 -0
- package/dist/actions/facewear-status.d.ts.map +1 -0
- package/dist/actions/facewear-status.js +66 -0
- package/dist/actions/facewear-status.js.map +1 -0
- package/dist/actions/microphone.d.ts +4 -0
- package/dist/actions/microphone.d.ts.map +1 -0
- package/dist/actions/microphone.js +63 -0
- package/dist/actions/microphone.js.map +1 -0
- package/dist/actions/view-actions.d.ts +23 -0
- package/dist/actions/view-actions.d.ts.map +1 -0
- package/dist/actions/view-actions.js +314 -0
- package/dist/actions/view-actions.js.map +1 -0
- package/dist/actions/vision-query.d.ts +4 -0
- package/dist/actions/vision-query.d.ts.map +1 -0
- package/dist/actions/vision-query.js +41 -0
- package/dist/actions/vision-query.js.map +1 -0
- package/dist/actions/xr-view-actions.d.ts +14 -0
- package/dist/actions/xr-view-actions.d.ts.map +1 -0
- package/dist/actions/xr-view-actions.js +29 -0
- package/dist/actions/xr-view-actions.js.map +1 -0
- package/dist/components/FacewearSpatialView.d.ts +50 -0
- package/dist/components/FacewearSpatialView.d.ts.map +1 -0
- package/dist/components/FacewearSpatialView.js +129 -0
- package/dist/components/FacewearSpatialView.js.map +1 -0
- package/dist/components/FacewearView.d.ts +17 -0
- package/dist/components/FacewearView.d.ts.map +1 -0
- package/dist/components/FacewearView.js +88 -0
- package/dist/components/FacewearView.js.map +1 -0
- package/dist/components/SmartglassesPanelView.d.ts +22 -0
- package/dist/components/SmartglassesPanelView.d.ts.map +1 -0
- package/dist/components/SmartglassesPanelView.js +140 -0
- package/dist/components/SmartglassesPanelView.js.map +1 -0
- package/dist/components/SmartglassesSpatialView.d.ts +46 -0
- package/dist/components/SmartglassesSpatialView.d.ts.map +1 -0
- package/dist/components/SmartglassesSpatialView.js +240 -0
- package/dist/components/SmartglassesSpatialView.js.map +1 -0
- package/dist/components/facewear-profiles.d.ts +27 -0
- package/dist/components/facewear-profiles.d.ts.map +1 -0
- package/dist/components/facewear-profiles.js +40 -0
- package/dist/components/facewear-profiles.js.map +1 -0
- package/dist/devices/apple-vision-pro.d.ts +7 -0
- package/dist/devices/apple-vision-pro.d.ts.map +1 -0
- package/dist/devices/apple-vision-pro.js +21 -0
- package/dist/devices/apple-vision-pro.js.map +1 -0
- package/dist/devices/even-realities.d.ts +7 -0
- package/dist/devices/even-realities.d.ts.map +1 -0
- package/dist/devices/even-realities.js +13 -0
- package/dist/devices/even-realities.js.map +1 -0
- package/dist/devices/meta-quest.d.ts +5 -0
- package/dist/devices/meta-quest.d.ts.map +1 -0
- package/dist/devices/meta-quest.js +21 -0
- package/dist/devices/meta-quest.js.map +1 -0
- package/dist/devices/registry.d.ts +19 -0
- package/dist/devices/registry.d.ts.map +1 -0
- package/dist/devices/registry.js +96 -0
- package/dist/devices/registry.js.map +1 -0
- package/dist/devices/xreal.d.ts +7 -0
- package/dist/devices/xreal.d.ts.map +1 -0
- package/dist/devices/xreal.js +19 -0
- package/dist/devices/xreal.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +260 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol/smartglasses.d.ts +306 -0
- package/dist/protocol/smartglasses.d.ts.map +1 -0
- package/dist/protocol/smartglasses.js +1485 -0
- package/dist/protocol/smartglasses.js.map +1 -0
- package/dist/protocol/xr.d.ts +137 -0
- package/dist/protocol/xr.d.ts.map +1 -0
- package/dist/protocol/xr.js +18 -0
- package/dist/protocol/xr.js.map +1 -0
- package/dist/providers/facewear-context.d.ts +3 -0
- package/dist/providers/facewear-context.d.ts.map +1 -0
- package/dist/providers/facewear-context.js +59 -0
- package/dist/providers/facewear-context.js.map +1 -0
- package/dist/providers/smartglasses-status.d.ts +3 -0
- package/dist/providers/smartglasses-status.d.ts.map +1 -0
- package/dist/providers/smartglasses-status.js +33 -0
- package/dist/providers/smartglasses-status.js.map +1 -0
- package/dist/register-terminal-view.d.ts +21 -0
- package/dist/register-terminal-view.d.ts.map +1 -0
- package/dist/register-terminal-view.js +70 -0
- package/dist/register-terminal-view.js.map +1 -0
- package/dist/register.d.ts +8 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +116 -0
- package/dist/register.js.map +1 -0
- package/dist/routes/connect.d.ts +3 -0
- package/dist/routes/connect.d.ts.map +1 -0
- package/dist/routes/connect.js +86 -0
- package/dist/routes/connect.js.map +1 -0
- package/dist/routes/device-config.d.ts +5 -0
- package/dist/routes/device-config.d.ts.map +1 -0
- package/dist/routes/device-config.js +56 -0
- package/dist/routes/device-config.js.map +1 -0
- package/dist/routes/simulator-route.d.ts +8 -0
- package/dist/routes/simulator-route.d.ts.map +1 -0
- package/dist/routes/simulator-route.js +32 -0
- package/dist/routes/simulator-route.js.map +1 -0
- package/dist/routes/status.d.ts +3 -0
- package/dist/routes/status.d.ts.map +1 -0
- package/dist/routes/status.js +34 -0
- package/dist/routes/status.js.map +1 -0
- package/dist/routes/view-host.d.ts +24 -0
- package/dist/routes/view-host.d.ts.map +1 -0
- package/dist/routes/view-host.js +339 -0
- package/dist/routes/view-host.js.map +1 -0
- package/dist/routes/views.d.ts +8 -0
- package/dist/routes/views.d.ts.map +1 -0
- package/dist/routes/views.js +31 -0
- package/dist/routes/views.js.map +1 -0
- package/dist/services/audio-pipeline.d.ts +20 -0
- package/dist/services/audio-pipeline.d.ts.map +1 -0
- package/dist/services/audio-pipeline.js +87 -0
- package/dist/services/audio-pipeline.js.map +1 -0
- package/dist/services/facewear-service.d.ts +26 -0
- package/dist/services/facewear-service.d.ts.map +1 -0
- package/dist/services/facewear-service.js +45 -0
- package/dist/services/facewear-service.js.map +1 -0
- package/dist/services/smartglasses-service.d.ts +244 -0
- package/dist/services/smartglasses-service.d.ts.map +1 -0
- package/dist/services/smartglasses-service.js +821 -0
- package/dist/services/smartglasses-service.js.map +1 -0
- package/dist/services/vision-pipeline.d.ts +16 -0
- package/dist/services/vision-pipeline.d.ts.map +1 -0
- package/dist/services/vision-pipeline.js +39 -0
- package/dist/services/vision-pipeline.js.map +1 -0
- package/dist/services/xr-session-service.d.ts +54 -0
- package/dist/services/xr-session-service.d.ts.map +1 -0
- package/dist/services/xr-session-service.js +345 -0
- package/dist/services/xr-session-service.js.map +1 -0
- package/dist/status-format.d.ts +15 -0
- package/dist/status-format.d.ts.map +1 -0
- package/dist/status-format.js +89 -0
- package/dist/status-format.js.map +1 -0
- package/dist/transport/even-bridge.d.ts +69 -0
- package/dist/transport/even-bridge.d.ts.map +1 -0
- package/dist/transport/even-bridge.js +510 -0
- package/dist/transport/even-bridge.js.map +1 -0
- package/dist/transport/mock.d.ts +42 -0
- package/dist/transport/mock.d.ts.map +1 -0
- package/dist/transport/mock.js +124 -0
- package/dist/transport/mock.js.map +1 -0
- package/dist/transport/noble.d.ts +62 -0
- package/dist/transport/noble.d.ts.map +1 -0
- package/dist/transport/noble.js +256 -0
- package/dist/transport/noble.js.map +1 -0
- package/dist/transport/types.d.ts +36 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +1 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/transport/web-bluetooth.d.ts +58 -0
- package/dist/transport/web-bluetooth.d.ts.map +1 -0
- package/dist/transport/web-bluetooth.js +164 -0
- package/dist/transport/web-bluetooth.js.map +1 -0
- package/dist/ui/FacewearAppView.d.ts +4 -0
- package/dist/ui/FacewearAppView.d.ts.map +1 -0
- package/dist/ui/FacewearAppView.js +257 -0
- package/dist/ui/FacewearAppView.js.map +1 -0
- package/dist/ui/SmartglassesView.d.ts +10 -0
- package/dist/ui/SmartglassesView.d.ts.map +1 -0
- package/dist/ui/SmartglassesView.helpers.d.ts +104 -0
- package/dist/ui/SmartglassesView.helpers.d.ts.map +1 -0
- package/dist/ui/SmartglassesView.helpers.js +261 -0
- package/dist/ui/SmartglassesView.helpers.js.map +1 -0
- package/dist/ui/SmartglassesView.js +1189 -0
- package/dist/ui/SmartglassesView.js.map +1 -0
- package/dist/ui/facewear-view-bundle.d.ts +5 -0
- package/dist/ui/facewear-view-bundle.d.ts.map +1 -0
- package/dist/ui/facewear-view-bundle.js +17 -0
- package/dist/ui/facewear-view-bundle.js.map +1 -0
- package/dist/views/bundle.js +2950 -0
- package/dist/views/bundle.js.map +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/protocol/smartglasses.ts"],"sourcesContent":["export type GlassSide = \"left\" | \"right\";\nexport type G1ConnectionReadyMode = \"lens-specific\" | \"official\" | \"android-f4\";\nexport type SmartglassesAudioEncoding = \"pcm16\" | \"lc3\" | \"unknown\";\n\nexport const EVEN_G1_UART = {\n service: \"6e400001-b5a3-f393-e0a9-e50e24dcca9e\",\n tx: \"6e400002-b5a3-f393-e0a9-e50e24dcca9e\",\n rx: \"6e400003-b5a3-f393-e0a9-e50e24dcca9e\",\n} as const;\n\nexport enum G1Command {\n StartAi = 0xf5,\n OpenMic = 0x0e,\n ReceiveMicData = 0xf1,\n Init = 0x4d,\n RightInit = 0xf4,\n Heartbeat = 0x25,\n Battery = 0x2c,\n SendResult = 0x4e,\n QuickNote = 0x21,\n Dashboard = 0x22,\n Notification = 0x4b,\n DashboardContent = 0x06,\n Navigation = 0x0a,\n TranslateSetup = 0x39,\n TranslateStart = 0x50,\n TranslateLanguages = 0x1c,\n TranslateOriginalText = 0x0f,\n TranslateTranslatedText = 0x0d,\n AppWhitelist = 0x04,\n ExitFunction = 0x18,\n SilentMode = 0x03,\n Brightness = 0x01,\n DashboardPosition = 0x26,\n HeadUpAngle = 0x0b,\n GlassesWear = 0x27,\n BmpData = 0x15,\n BmpCrc = 0x16,\n BmpEnd = 0x20,\n Note = 0x1e,\n GetSerial = 0x34,\n}\n\nexport enum G1DashboardLayout {\n Full = \"full\",\n Dual = \"dual\",\n Minimal = \"minimal\",\n}\n\nexport enum G1WeatherIcon {\n Nothing = 0x00,\n Night = 0x01,\n Clouds = 0x02,\n Drizzle = 0x03,\n HeavyDrizzle = 0x04,\n Rain = 0x05,\n HeavyRain = 0x06,\n Thunder = 0x07,\n Thunderstorm = 0x08,\n Snow = 0x09,\n Mist = 0x0a,\n Fog = 0x0b,\n Sand = 0x0c,\n Squalls = 0x0d,\n Tornado = 0x0e,\n FreezingRain = 0x0f,\n Sunny = 0x10,\n}\n\nexport enum G1TemperatureUnit {\n Celsius = \"celsius\",\n Fahrenheit = \"fahrenheit\",\n}\n\nexport enum G1TimeFormat {\n TwentyFourHour = \"24h\",\n TwelveHour = \"12h\",\n}\n\nexport enum G1NavigationTurn {\n StraightDot = 0x01,\n Straight = 0x02,\n Right = 0x03,\n Left = 0x04,\n SlightRight = 0x05,\n SlightLeft = 0x06,\n StrongRight = 0x07,\n StrongLeft = 0x08,\n UTurnLeft = 0x09,\n UTurnRight = 0x0a,\n Merge = 0x0b,\n SlightRightAtFork = 0x22,\n SlightLeftAtFork = 0x23,\n}\n\nexport enum G1TranslateLanguage {\n Chinese = 0x01,\n English = 0x02,\n French = 0x05,\n Dutch = 0x09,\n}\n\nexport enum G1SubCommand {\n Exit = 0x00,\n PageControl = 0x01,\n Start = 0x17,\n Stop = 0x18,\n}\n\nexport enum G1MicStatus {\n Disable = 0x00,\n Enable = 0x01,\n}\n\nexport enum G1ResponseStatus {\n Success = 0xc9,\n Failure = 0xca,\n}\n\nexport enum G1ScreenAction {\n NewContent = 0x01,\n}\n\nexport enum G1AiStatus {\n Displaying = 0x30,\n DisplayComplete = 0x40,\n ManualMode = 0x50,\n NetworkError = 0x60,\n}\n\nexport enum G1TextStatus {\n TextShow = 0x70,\n}\n\nexport enum G1SilentModeStatus {\n Off = 0x0a,\n On = 0x0c,\n}\n\nexport enum G1DashboardState {\n Off = 0x00,\n On = 0x01,\n}\n\nexport enum G1GlassesWearStatus {\n Off = 0x00,\n On = 0x01,\n}\n\nexport enum G1VoiceNoteSubCommand {\n RequestAudioInfo = 0x01,\n RequestAudioData = 0x02,\n DeleteAudioStream = 0x04,\n DeleteAll = 0x05,\n}\n\nexport enum G1InteractionCode {\n DoubleTap = 0x00,\n SingleTap = 0x01,\n LongPress = 0x17,\n StopAiRecording = 0x18,\n SilentModeOn = 0x04,\n SilentModeOff = 0x05,\n OpenDashboardStart = 0x02,\n CloseDashboardStart = 0x03,\n OpenDashboardConfirm = 0x1e,\n CloseDashboardConfirm = 0x1f,\n}\n\nexport interface DisplayPage {\n pageNumber: number;\n maxPages: number;\n text: string;\n screenStatus: number;\n}\n\nexport interface G1NotificationPayload {\n msgId?: number;\n type?: number;\n appIdentifier: string;\n title: string;\n subtitle?: string;\n message: string;\n displayName?: string;\n timeS?: number;\n date?: string;\n}\n\nexport interface G1DashboardTimeWeatherPayload {\n seqId?: number;\n timestampMs?: number;\n timezoneOffsetSeconds?: number;\n temperatureInCelsius: number;\n weatherIcon?: number;\n temperatureUnit?: G1TemperatureUnit;\n timeFormat?: G1TimeFormat;\n}\n\nexport interface G1NavigationDirectionsPayload {\n seqId: number;\n totalDuration: string;\n totalDistance: string;\n direction: string;\n distance: string;\n speed: string;\n directionTurn: number;\n customX?: [number, number] | number[];\n customY?: number;\n}\n\nexport interface G1VoiceNoteEntry {\n index: number;\n timestamp: number;\n crc: number;\n}\n\nexport interface G1Event {\n side: GlassSide;\n raw: Uint8Array;\n type:\n | \"state\"\n | \"dashboard\"\n | \"init\"\n | \"mic-response\"\n | \"mic-data\"\n | \"display-result\"\n | \"notification\"\n | \"voice-note-list\"\n | \"voice-note-audio\"\n | \"serial\"\n | \"battery-status\"\n | \"heartbeat\"\n | \"response\"\n | \"error\"\n | \"unknown\";\n code?: number;\n label?: string;\n micEnabled?: boolean;\n micRequested?: boolean;\n responseStatus?: number;\n responseOk?: boolean;\n stateCategory?: \"interaction\" | \"physical\" | \"battery\" | \"device\";\n stateName?: string;\n audioData?: Uint8Array;\n audioEncoding?: SmartglassesAudioEncoding;\n /**\n * Decoded 16-bit PCM bytes. Direct G1 0xF1 microphone notifications are LC3\n * and are exposed through audioData instead.\n */\n audioPcm?: Uint8Array;\n sequence?: number;\n syncId?: number;\n subcommand?: number;\n displaySeq?: number;\n totalPackages?: number;\n currentPackage?: number;\n screenStatus?: number;\n charPosition?: number;\n pageNumber?: number;\n maxPages?: number;\n text?: string;\n notificationId?: number;\n notificationChunk?: Uint8Array;\n voiceNotes?: G1VoiceNoteEntry[];\n serialNumber?: string;\n totalPackets?: number;\n currentPacket?: number;\n noteIndex?: number;\n batteryPercent?: number;\n batteryFlags?: number;\n batteryVoltageMv?: number;\n}\n\nexport type G1MicrophoneInteractionAction = \"enable\" | \"disable\";\n\nexport function microphoneActionForInteractionEvent(\n event: Pick<G1Event, \"type\" | \"label\">,\n): G1MicrophoneInteractionAction | null {\n if (event.type !== \"state\") return null;\n if (event.label === \"single_tap\" || event.label === \"long_press\") {\n return \"enable\";\n }\n if (event.label === \"double_tap\" || event.label === \"stop_ai_recording\") {\n return \"disable\";\n }\n return null;\n}\n\nexport const G1_DISPLAY = {\n displayWidthPx: 576,\n charsPerLine: 40,\n linesPerPage: 5,\n maxTextLength: 40 * 5,\n maxPayloadBytes: 191,\n};\n\nconst G1_GLYPH_WIDTHS = new Map<string, number>(\n Object.entries({\n \" \": 2,\n \"!\": 1,\n '\"': 2,\n \"#\": 6,\n $: 5,\n \"%\": 6,\n \"&\": 7,\n \"'\": 1,\n \"(\": 2,\n \")\": 2,\n \"*\": 3,\n \"+\": 4,\n \",\": 1,\n \"-\": 4,\n \".\": 1,\n \"/\": 3,\n \"0\": 5,\n \"1\": 3,\n \"2\": 5,\n \"3\": 5,\n \"4\": 5,\n \"5\": 5,\n \"6\": 5,\n \"7\": 5,\n \"8\": 5,\n \"9\": 5,\n \":\": 1,\n \";\": 1,\n \"<\": 4,\n \"=\": 4,\n \">\": 4,\n \"?\": 5,\n \"@\": 7,\n A: 6,\n B: 5,\n C: 5,\n D: 5,\n E: 4,\n F: 4,\n G: 5,\n H: 5,\n I: 2,\n J: 3,\n K: 5,\n L: 4,\n M: 7,\n N: 5,\n O: 5,\n P: 5,\n Q: 5,\n R: 5,\n S: 5,\n T: 5,\n U: 5,\n V: 6,\n W: 7,\n X: 6,\n Y: 6,\n Z: 5,\n \"[\": 2,\n \"\\\\\": 3,\n \"]\": 2,\n \"^\": 4,\n _: 3,\n \"`\": 2,\n a: 5,\n b: 4,\n c: 4,\n d: 4,\n e: 4,\n f: 4,\n g: 4,\n h: 4,\n i: 1,\n j: 2,\n k: 4,\n l: 1,\n m: 7,\n n: 4,\n o: 4,\n p: 4,\n q: 4,\n r: 3,\n s: 4,\n t: 3,\n u: 5,\n v: 5,\n w: 7,\n x: 5,\n y: 5,\n z: 4,\n \"{\": 3,\n \"|\": 1,\n \"}\": 3,\n \"~\": 7,\n }),\n);\n\nexport const G1_BMP = {\n width: 576,\n height: 136,\n bitsPerPixel: 1,\n};\n\nconst INTERACTION_LABELS = new Map<number, string>([\n [G1InteractionCode.DoubleTap, \"double_tap\"],\n [G1InteractionCode.SingleTap, \"single_tap\"],\n [G1InteractionCode.LongPress, \"long_press\"],\n [G1InteractionCode.StopAiRecording, \"stop_ai_recording\"],\n [G1InteractionCode.SilentModeOn, \"silent_mode_on\"],\n [G1InteractionCode.SilentModeOff, \"silent_mode_off\"],\n [G1InteractionCode.OpenDashboardStart, \"open_dashboard_start\"],\n [G1InteractionCode.CloseDashboardStart, \"close_dashboard_start\"],\n [G1InteractionCode.OpenDashboardConfirm, \"open_dashboard_confirm\"],\n [G1InteractionCode.CloseDashboardConfirm, \"close_dashboard_confirm\"],\n]);\n\nconst PHYSICAL_LABELS = new Map<number, string>([\n [0x06, \"wearing\"],\n [0x07, \"transitioning\"],\n [0x08, \"cradle_open\"],\n [0x09, \"charged_in_cradle\"],\n [0x0b, \"cradle_closed\"],\n]);\n\nconst BATTERY_LABELS = new Map<number, string>([\n [0x09, \"glasses_fully_charged\"],\n [0x0e, \"cradle_charging_cable_changed\"],\n [0x0f, \"cradle_fully_charged\"],\n]);\n\nconst DEVICE_LABELS = new Map<number, string>([\n [0x0a, \"device_unknown_0a\"],\n [0x11, \"connected\"],\n [0x12, \"device_unknown_12\"],\n [0x14, \"device_unknown_14\"],\n [0x15, \"device_unknown_15\"],\n]);\n\nfunction classifyStateCode(code: number | undefined): {\n category: NonNullable<G1Event[\"stateCategory\"]>;\n label: string;\n name: string;\n} | null {\n if (code === undefined) return null;\n const interaction = INTERACTION_LABELS.get(code);\n if (interaction)\n return { category: \"interaction\", label: interaction, name: interaction };\n const physical = PHYSICAL_LABELS.get(code);\n if (physical)\n return { category: \"physical\", label: physical, name: physical };\n const battery = BATTERY_LABELS.get(code);\n if (battery) return { category: \"battery\", label: battery, name: battery };\n const device = DEVICE_LABELS.get(code);\n if (device) return { category: \"device\", label: device, name: device };\n return null;\n}\n\nexport function measureG1DisplayText(text: string): number {\n let width = 0;\n for (const char of text) width += measureG1DisplayChar(char);\n return width;\n}\n\nfunction measureG1DisplayChar(char: string): number {\n const codePoint = char.codePointAt(0) ?? 0;\n if (isKorean(codePoint)) return 24;\n if (isCjk(codePoint) || isHiragana(codePoint) || isKatakana(codePoint))\n return 18;\n if (isCyrillic(codePoint)) return 18;\n const glyphWidth = G1_GLYPH_WIDTHS.get(char);\n return glyphWidth === undefined ? 16 : (glyphWidth + 1) * 2;\n}\n\nfunction isCjk(codePoint: number): boolean {\n return (\n (codePoint >= 0x3400 && codePoint <= 0x4dbf) ||\n (codePoint >= 0x4e00 && codePoint <= 0x9fff) ||\n (codePoint >= 0xf900 && codePoint <= 0xfaff)\n );\n}\n\nfunction isHiragana(codePoint: number): boolean {\n return codePoint >= 0x3040 && codePoint <= 0x309f;\n}\n\nfunction isKatakana(codePoint: number): boolean {\n return codePoint >= 0x30a0 && codePoint <= 0x30ff;\n}\n\nfunction isKorean(codePoint: number): boolean {\n return codePoint >= 0xac00 && codePoint <= 0xd7af;\n}\n\nfunction isCyrillic(codePoint: number): boolean {\n return codePoint >= 0x0400 && codePoint <= 0x04ff;\n}\n\nfunction fitsG1DisplayLine(text: string, maxWidthPx: number): boolean {\n return measureG1DisplayText(text) <= maxWidthPx;\n}\n\nexport function formatDisplayLines(\n text: string,\n options: number | { charsPerLine?: number; maxWidthPx?: number } = {},\n): string[] {\n const charsPerLine =\n typeof options === \"number\" ? options : options.charsPerLine;\n const maxWidthPx =\n typeof options === \"number\"\n ? undefined\n : (options.maxWidthPx ?? G1_DISPLAY.displayWidthPx);\n if (charsPerLine !== undefined)\n return formatDisplayLinesByCharacters(text, charsPerLine);\n return formatDisplayLinesByPixels(\n text,\n maxWidthPx ?? G1_DISPLAY.displayWidthPx,\n );\n}\n\nfunction formatDisplayLinesByCharacters(\n text: string,\n charsPerLine: number,\n): string[] {\n const lines: string[] = [];\n for (const paragraph of text\n .split(/\\r?\\n/)\n .map((p) => p.trim())\n .filter(Boolean)) {\n let rest = paragraph;\n while (rest.length > charsPerLine) {\n let splitAt = rest.lastIndexOf(\" \", charsPerLine);\n if (splitAt < 1) splitAt = charsPerLine;\n lines.push(rest.slice(0, splitAt).trimEnd());\n rest = rest.slice(splitAt).trimStart();\n }\n if (rest) lines.push(rest);\n }\n return lines.length ? lines : [\"\"];\n}\n\nfunction formatDisplayLinesByPixels(\n text: string,\n maxWidthPx: number,\n): string[] {\n const lines: string[] = [];\n for (const paragraph of text.split(/\\r?\\n/)) {\n const trimmed = paragraph.trim();\n if (!trimmed) {\n if (lines.length > 0) lines.push(\"\");\n continue;\n }\n lines.push(...wrapDisplayParagraphByPixels(trimmed, maxWidthPx));\n }\n return lines.length ? lines : [\"\"];\n}\n\nfunction wrapDisplayParagraphByPixels(\n paragraph: string,\n maxWidthPx: number,\n): string[] {\n if (fitsG1DisplayLine(paragraph, maxWidthPx)) return [paragraph];\n const lines: string[] = [];\n let current = \"\";\n for (const word of paragraph.split(/\\s+/).filter(Boolean)) {\n const candidate = current ? `${current} ${word}` : word;\n if (fitsG1DisplayLine(candidate, maxWidthPx)) {\n current = candidate;\n continue;\n }\n if (current) {\n lines.push(current);\n current = \"\";\n }\n const wordLines = breakDisplayTokenByPixels(word, maxWidthPx);\n lines.push(...wordLines.slice(0, -1));\n current = wordLines.at(-1) ?? \"\";\n }\n if (current) lines.push(current);\n return lines;\n}\n\nfunction breakDisplayTokenByPixels(\n token: string,\n maxWidthPx: number,\n): string[] {\n const lines: string[] = [];\n let current = \"\";\n for (const char of Array.from(token)) {\n const candidate = current + char;\n if (fitsG1DisplayLine(candidate, maxWidthPx)) {\n current = candidate;\n continue;\n }\n if (current) lines.push(current);\n current = char;\n }\n if (current) lines.push(current);\n return lines.length ? lines : [\"\"];\n}\n\nexport function paginateDisplayText(\n text: string,\n options: { charsPerLine?: number; linesPerPage?: number } = {},\n): DisplayPage[] {\n const charsPerLine = options.charsPerLine ?? G1_DISPLAY.charsPerLine;\n const linesPerPage = options.linesPerPage ?? G1_DISPLAY.linesPerPage;\n const lines = formatDisplayLines(\n text,\n options.charsPerLine === undefined\n ? { maxWidthPx: G1_DISPLAY.displayWidthPx }\n : { charsPerLine },\n );\n const maxPages = Math.max(1, Math.ceil(lines.length / linesPerPage));\n const pages: DisplayPage[] = [];\n\n for (let pageIndex = 0; pageIndex < maxPages; pageIndex++) {\n const pageLines = lines.slice(\n pageIndex * linesPerPage,\n (pageIndex + 1) * linesPerPage,\n );\n const missing = linesPerPage - pageLines.length;\n if (missing > 0) {\n const before = Math.floor(missing / 2);\n const after = missing - before;\n pageLines.unshift(...Array.from({ length: before }, () => \"\"));\n pageLines.push(...Array.from({ length: after }, () => \"\"));\n }\n pages.push({\n pageNumber: pageIndex + 1,\n maxPages,\n text: pageLines.join(\"\\n\"),\n screenStatus:\n pageIndex === maxPages - 1\n ? G1AiStatus.DisplayComplete\n : G1AiStatus.Displaying | G1ScreenAction.NewContent,\n });\n }\n return pages;\n}\n\nexport function encodeTextPacket(page: DisplayPage, seq = 0): Uint8Array {\n const data = new TextEncoder().encode(page.text);\n if (data.byteLength > G1_DISPLAY.maxPayloadBytes) {\n throw new RangeError(\n `G1 display payload is ${data.byteLength} bytes; use encodeTextPackets for payloads over ${G1_DISPLAY.maxPayloadBytes} bytes`,\n );\n }\n return encodeTextPacketChunk(page, data, seq, 1, 0);\n}\n\nexport function encodeTextPackets(page: DisplayPage, seq = 0): Uint8Array[] {\n const chunks = splitUtf8Chunks(page.text, G1_DISPLAY.maxPayloadBytes);\n const totalPackages = chunks.length;\n const packets: Uint8Array[] = [];\n let charPosition = 0;\n for (const [currentPackage, chunk] of chunks.entries()) {\n packets.push(\n encodeTextPacketChunk(\n page,\n chunk,\n seq,\n totalPackages,\n currentPackage,\n charPosition,\n ),\n );\n charPosition += chunk.length;\n }\n return packets;\n}\n\nfunction splitUtf8Chunks(text: string, maxBytes: number): Uint8Array[] {\n const encoder = new TextEncoder();\n if (text.length === 0) return [new Uint8Array()];\n const chunks: Uint8Array[] = [];\n let current = \"\";\n for (const char of text) {\n const next = current + char;\n const nextBytes = encoder.encode(next);\n if (nextBytes.byteLength > maxBytes && current) {\n chunks.push(encoder.encode(current));\n current = char;\n continue;\n }\n if (nextBytes.byteLength > maxBytes) {\n throw new RangeError(\n `Single UTF-8 character exceeds G1 display packet payload limit of ${maxBytes} bytes`,\n );\n }\n current = next;\n }\n if (current || chunks.length === 0) chunks.push(encoder.encode(current));\n return chunks;\n}\n\nfunction encodeTextPacketChunk(\n page: DisplayPage,\n data: Uint8Array,\n seq: number,\n totalPackages: number,\n currentPackage: number,\n charPosition = 0,\n): Uint8Array {\n const packet = new Uint8Array(9 + data.length);\n packet.set([\n G1Command.SendResult,\n seq & 0xff,\n totalPackages & 0xff,\n currentPackage & 0xff,\n page.screenStatus & 0xff,\n (charPosition >>> 8) & 0xff,\n charPosition & 0xff,\n page.pageNumber & 0xff,\n page.maxPages & 0xff,\n ]);\n packet.set(data, 9);\n return packet;\n}\n\nexport function encodeMicCommand(enabled: boolean): Uint8Array {\n return Uint8Array.from([\n G1Command.OpenMic,\n enabled ? G1MicStatus.Enable : G1MicStatus.Disable,\n ]);\n}\n\nexport function encodeHeartbeat(seq: number): Uint8Array {\n const s = seq & 0xff;\n return Uint8Array.from([G1Command.Heartbeat, 0x06, 0x00, s, 0x04, s]);\n}\n\nexport function encodeBatteryStatusRequest(): Uint8Array {\n return Uint8Array.from([G1Command.Battery, 0x01]);\n}\n\nexport function encodeConnectionReady(\n side: GlassSide,\n mode: G1ConnectionReadyMode = \"lens-specific\",\n): Uint8Array {\n return Uint8Array.from([\n mode === \"android-f4\"\n ? G1Command.RightInit\n : mode === \"official\" || side === \"left\"\n ? G1Command.Init\n : G1Command.RightInit,\n 0x01,\n ]);\n}\n\nexport function encodeStartAi(\n subcommand: G1SubCommand,\n param: Uint8Array = new Uint8Array(),\n): Uint8Array {\n const packet = new Uint8Array(2 + param.length);\n packet.set([G1Command.StartAi, subcommand]);\n packet.set(param, 2);\n return packet;\n}\n\nexport function encodeExitFunction(): Uint8Array {\n return Uint8Array.from([G1Command.ExitFunction]);\n}\n\nexport function encodeGetSerial(): Uint8Array {\n return Uint8Array.from([G1Command.GetSerial]);\n}\n\nexport function encodeClearScreen(): Uint8Array {\n return Uint8Array.from([\n G1Command.StartAi,\n G1SubCommand.Stop,\n 0x00,\n 0x00,\n 0x00,\n ]);\n}\n\nexport function encodeSilentMode(enabled: boolean): Uint8Array {\n return Uint8Array.from([\n G1Command.SilentMode,\n enabled ? G1SilentModeStatus.On : G1SilentModeStatus.Off,\n 0x00,\n ]);\n}\n\nexport function encodeBrightness(level: number, auto = false): Uint8Array {\n if (!Number.isInteger(level) || level < 0 || level > 0x29) {\n throw new RangeError(\n \"Brightness level must be an integer between 0 and 0x29\",\n );\n }\n return Uint8Array.from([\n G1Command.Brightness,\n level & 0xff,\n auto ? 0x01 : 0x00,\n ]);\n}\n\nexport function encodeDashboard(\n state: G1DashboardState | boolean,\n position = 0,\n): Uint8Array {\n if (!Number.isInteger(position) || position < 0 || position > 8) {\n throw new RangeError(\n \"Dashboard position must be an integer between 0 and 8\",\n );\n }\n const stateValue =\n typeof state === \"boolean\"\n ? state\n ? G1DashboardState.On\n : G1DashboardState.Off\n : state;\n return Uint8Array.from([\n G1Command.DashboardPosition,\n 0x07,\n 0x00,\n 0x01,\n 0x02,\n stateValue,\n position & 0xff,\n ]);\n}\n\nexport function encodeDashboardPosition(\n height: number,\n depth: number,\n seqId = 1,\n): Uint8Array {\n if (!Number.isInteger(height) || height < 0 || height > 8) {\n throw new RangeError(\"Dashboard height must be an integer between 0 and 8\");\n }\n if (!Number.isInteger(depth) || depth < 1 || depth > 9) {\n throw new RangeError(\"Dashboard depth must be an integer between 1 and 9\");\n }\n return Uint8Array.from([\n G1Command.DashboardPosition,\n 0x08,\n 0x00,\n seqId & 0xff,\n 0x02,\n 0x01,\n height & 0xff,\n depth & 0xff,\n ]);\n}\n\nexport function encodeDashboardLayout(layout: G1DashboardLayout): Uint8Array {\n const layoutBytes =\n layout === G1DashboardLayout.Full\n ? [0x08, 0x06, 0x00, 0x00]\n : layout === G1DashboardLayout.Dual\n ? [0x1e, 0x06, 0x01, 0x00]\n : [0x31, 0x06, 0x02, 0x00];\n return Uint8Array.from([\n G1Command.DashboardContent,\n 0x07,\n 0x00,\n ...layoutBytes,\n ]);\n}\n\nexport function encodeDashboardCalendarItem(payload: {\n name: string;\n time: string;\n location: string;\n}): Uint8Array {\n const name = new TextEncoder().encode(payload.name);\n const time = new TextEncoder().encode(payload.time);\n const location = new TextEncoder().encode(payload.location);\n for (const [field, bytes] of [\n [\"name\", name],\n [\"time\", time],\n [\"location\", location],\n ] as const) {\n if (bytes.length > 255)\n throw new RangeError(\n `Dashboard calendar ${field} must be at most 255 bytes`,\n );\n }\n const prefix = [\n 0x00, 0x6d, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x01,\n ];\n const body = new Uint8Array(\n prefix.length + 6 + name.length + time.length + location.length,\n );\n let offset = 0;\n body.set(prefix, offset);\n offset += prefix.length;\n body.set([0x01, name.length], offset);\n offset += 2;\n body.set(name, offset);\n offset += name.length;\n body.set([0x02, time.length], offset);\n offset += 2;\n body.set(time, offset);\n offset += time.length;\n body.set([0x03, location.length], offset);\n offset += 2;\n body.set(location, offset);\n return Uint8Array.from([\n G1Command.DashboardContent,\n (body.length + 2) & 0xff,\n ...body,\n ]);\n}\n\nexport function encodeDashboardTimeWeather(\n payload: G1DashboardTimeWeatherPayload,\n): Uint8Array {\n if (\n !Number.isInteger(payload.temperatureInCelsius) ||\n payload.temperatureInCelsius < -128 ||\n payload.temperatureInCelsius > 127\n ) {\n throw new RangeError(\"Dashboard temperature must fit in signed 8 bits\");\n }\n const seqId = payload.seqId ?? 0;\n const timestampMs = payload.timestampMs ?? Date.now();\n const timezoneOffsetSeconds =\n payload.timezoneOffsetSeconds ??\n -new Date(timestampMs).getTimezoneOffset() * 60;\n const localMs = timestampMs + timezoneOffsetSeconds * 1000;\n const out = new Uint8Array(21);\n const view = new DataView(out.buffer);\n out.set([G1Command.DashboardContent, 0x15, 0x00, seqId & 0xff, 0x01]);\n view.setUint32(5, Math.floor(localMs / 1000), true);\n view.setBigUint64(9, BigInt(Math.trunc(localMs)), true);\n out[17] = (payload.weatherIcon ?? G1WeatherIcon.Nothing) & 0xff;\n out[18] = payload.temperatureInCelsius & 0xff;\n out[19] =\n payload.temperatureUnit === G1TemperatureUnit.Fahrenheit ? 0x01 : 0x00;\n out[20] = payload.timeFormat === G1TimeFormat.TwelveHour ? 0x01 : 0x00;\n return out;\n}\n\nexport function encodeHeadUpAngle(angle: number): Uint8Array {\n if (!Number.isInteger(angle) || angle < 0 || angle > 60) {\n throw new RangeError(\n \"Head-up display angle must be an integer between 0 and 60\",\n );\n }\n return Uint8Array.from([G1Command.HeadUpAngle, angle & 0xff, 0x01]);\n}\n\nexport function encodeG1Setup(\n payload: string | Record<string, unknown> | unknown[],\n): Uint8Array[] {\n const text = typeof payload === \"string\" ? payload : JSON.stringify(payload);\n const data = new TextEncoder().encode(text);\n const maxPayload = 176;\n const totalPackets = Math.max(1, Math.ceil(data.byteLength / maxPayload));\n const packets: Uint8Array[] = [];\n for (let index = 0; index < totalPackets; index++) {\n const chunk = data.slice(index * maxPayload, (index + 1) * maxPayload);\n const packet = new Uint8Array(3 + chunk.length);\n packet.set([G1Command.AppWhitelist, totalPackets & 0xff, index & 0xff]);\n packet.set(chunk, 3);\n packets.push(packet);\n }\n return packets;\n}\n\nexport function encodeNavigationInit(seqId: number): Uint8Array {\n return Uint8Array.from([\n G1Command.Navigation,\n 0x06,\n 0x00,\n seqId & 0xff,\n 0x00,\n 0x01,\n ]);\n}\n\nexport function encodeNavigationDirections(\n payload: G1NavigationDirectionsPayload,\n): Uint8Array {\n const encoder = new TextEncoder();\n const totalDuration = encoder.encode(payload.totalDuration);\n const totalDistance = encoder.encode(payload.totalDistance);\n const direction = encoder.encode(payload.direction);\n const distance = encoder.encode(payload.distance);\n const speed = encoder.encode(payload.speed);\n const customX = payload.customX ?? [0x00, 0x00];\n const body = new Uint8Array(\n 8 +\n totalDuration.length +\n totalDistance.length +\n direction.length +\n distance.length +\n speed.length +\n 5,\n );\n let offset = 0;\n body.set(\n [\n 0x00,\n payload.seqId & 0xff,\n 0x01,\n payload.directionTurn & 0xff,\n customX[0] ?? 0,\n customX[1] ?? 0,\n payload.customY ?? 0,\n 0x00,\n ],\n offset,\n );\n offset += 8;\n for (const bytes of [\n totalDuration,\n totalDistance,\n direction,\n distance,\n speed,\n ]) {\n body.set(bytes, offset);\n offset += bytes.length;\n body[offset++] = 0x00;\n }\n return Uint8Array.from([\n G1Command.Navigation,\n (body.length + 2) & 0xff,\n ...body,\n ]);\n}\n\nexport function encodeNavigationPrimaryImage(\n image: ArrayLike<number>,\n overlay: ArrayLike<number>,\n seqId = 0,\n): Uint8Array[] {\n validateBitPlanes(image, overlay, 136 * 136, \"primary navigation image\");\n return encodeNavigationImagePackets(\n runLengthEncodeBits([...Array.from(image), ...Array.from(overlay)]),\n 0x02,\n seqId,\n false,\n );\n}\n\nexport function encodeNavigationSecondaryImage(\n image: ArrayLike<number>,\n overlay: ArrayLike<number>,\n seqId = 0,\n): Uint8Array[] {\n validateBitPlanes(image, overlay, 488 * 136, \"secondary navigation image\");\n return encodeNavigationImagePackets(\n [...Array.from(image), ...Array.from(overlay)],\n 0x03,\n seqId,\n true,\n );\n}\n\nexport function encodeNavigationPoller(\n seqId: number,\n pollerSeqId: number,\n): Uint8Array {\n return Uint8Array.from([\n G1Command.Navigation,\n 0x06,\n 0x00,\n seqId & 0xff,\n 0x04,\n pollerSeqId & 0xff,\n ]);\n}\n\nexport function encodeNavigationEnd(seqId: number): Uint8Array {\n return Uint8Array.from([\n G1Command.Navigation,\n 0x06,\n 0x00,\n seqId & 0xff,\n 0x05,\n 0x01,\n ]);\n}\n\nexport function encodeTranslateSetup(): Uint8Array {\n return Uint8Array.from([G1Command.TranslateSetup, 0x05, 0x00, 0x00, 0x13]);\n}\n\nexport function encodeTranslateStart(): Uint8Array {\n return Uint8Array.from([\n G1Command.TranslateStart,\n 0x06,\n 0x00,\n 0x00,\n 0x01,\n 0x01,\n ]);\n}\n\nexport function encodeTranslateLanguages(\n fromLanguage: number,\n toLanguage: number,\n): Uint8Array {\n return Uint8Array.from([\n G1Command.TranslateLanguages,\n 0x00,\n fromLanguage & 0xff,\n toLanguage & 0xff,\n ]);\n}\n\nexport function encodeTranslateText(\n kind: \"original\" | \"translated\",\n text: string,\n syncId: number,\n): Uint8Array {\n const encoded = new TextEncoder().encode(text);\n const command =\n kind === \"original\"\n ? G1Command.TranslateOriginalText\n : G1Command.TranslateTranslatedText;\n return Uint8Array.from([\n command,\n syncId & 0xff,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n text ? 0x20 : 0x00,\n 0x0d,\n ...encoded,\n ]);\n}\n\nexport function encodeGlassesWear(enabled: boolean): Uint8Array {\n return Uint8Array.from([\n G1Command.GlassesWear,\n enabled ? G1GlassesWearStatus.On : G1GlassesWearStatus.Off,\n ]);\n}\n\nexport function encodeAppWhitelist(\n whitelist: string | Record<string, unknown> | unknown[],\n): Uint8Array[] {\n const text =\n typeof whitelist === \"string\" ? whitelist : JSON.stringify(whitelist);\n const data = new TextEncoder().encode(text);\n const maxPayload = 177;\n const totalPackets = Math.max(1, Math.ceil(data.byteLength / maxPayload));\n const packets: Uint8Array[] = [];\n for (let seq = 0; seq < totalPackets; seq++) {\n const start = seq * maxPayload;\n const chunk = data.slice(start, start + maxPayload);\n const packet = new Uint8Array(3 + chunk.length);\n packet.set([G1Command.AppWhitelist, totalPackets & 0xff, seq & 0xff]);\n packet.set(chunk, 3);\n packets.push(packet);\n }\n return packets;\n}\n\nexport function encodeNoteDelete(noteNumber: number): Uint8Array {\n validateNoteNumber(noteNumber);\n return Uint8Array.from([\n G1Command.Note,\n 0x10,\n 0x00,\n 0xe0,\n 0x03,\n 0x01,\n 0x00,\n 0x01,\n 0x00,\n noteNumber,\n 0x00,\n 0x01,\n 0x00,\n 0x01,\n 0x00,\n 0x00,\n ]);\n}\n\nexport function encodeNoteAdd(\n noteNumber: number,\n title: string,\n text: string,\n version = Date.now(),\n): Uint8Array {\n validateNoteNumber(noteNumber);\n const titleBytes = new TextEncoder().encode(title);\n const textBytes = new TextEncoder().encode(text);\n if (titleBytes.length > 255 || textBytes.length > 255) {\n throw new RangeError(\n \"G1 note title and text must each encode to at most 255 bytes\",\n );\n }\n const fixed = Uint8Array.from([0x03, 0x01, 0x00, 0x01, 0x00]);\n const payloadLength =\n 1 +\n 1 +\n fixed.length +\n 1 +\n 1 +\n 1 +\n titleBytes.length +\n 1 +\n 1 +\n textBytes.length +\n 2;\n const out = new Uint8Array(\n 4 + fixed.length + 3 + titleBytes.length + 2 + textBytes.length,\n );\n let offset = 0;\n out.set(\n [\n G1Command.Note,\n payloadLength & 0xff,\n 0x00,\n Math.floor(version / 1000) & 0xff,\n ],\n offset,\n );\n offset += 4;\n out.set(fixed, offset);\n offset += fixed.length;\n out.set([noteNumber, 0x01, titleBytes.length & 0xff], offset);\n offset += 3;\n out.set(titleBytes, offset);\n offset += titleBytes.length;\n out.set([textBytes.length & 0xff, 0x00], offset);\n offset += 2;\n out.set(textBytes, offset);\n return out;\n}\n\nexport function encodeVoiceNoteFetch(\n noteIndex: number,\n syncId: number,\n): Uint8Array {\n validateVoiceNoteIndex(noteIndex);\n return Uint8Array.from([\n G1Command.Note,\n 0x06,\n 0x00,\n syncId & 0xff,\n G1VoiceNoteSubCommand.RequestAudioData,\n noteIndex & 0xff,\n ]);\n}\n\nexport function encodeVoiceNoteList(syncId: number): Uint8Array {\n return Uint8Array.from([\n G1Command.Note,\n 0x06,\n 0x00,\n syncId & 0xff,\n G1VoiceNoteSubCommand.RequestAudioInfo,\n 0x00,\n ]);\n}\n\nexport function encodeVoiceNoteDelete(\n noteIndex: number,\n syncId: number,\n): Uint8Array {\n validateVoiceNoteIndex(noteIndex);\n return Uint8Array.from([\n G1Command.Note,\n 0x06,\n 0x00,\n syncId & 0xff,\n G1VoiceNoteSubCommand.DeleteAudioStream,\n noteIndex & 0xff,\n ]);\n}\n\nexport function encodeVoiceNoteDeleteAll(syncId: number): Uint8Array {\n return Uint8Array.from([\n G1Command.Note,\n 0x06,\n 0x00,\n syncId & 0xff,\n G1VoiceNoteSubCommand.DeleteAll,\n 0x00,\n ]);\n}\n\nexport function encodeNotification(\n payload: G1NotificationPayload,\n): Uint8Array[] {\n const nowSeconds = Math.floor(Date.now() / 1000);\n const model = {\n ncs_notification: {\n msg_id: payload.msgId ?? nowSeconds,\n type: payload.type ?? 1,\n app_identifier: payload.appIdentifier,\n title: payload.title,\n subtitle: payload.subtitle ?? \"\",\n message: payload.message,\n time_s: payload.timeS ?? nowSeconds,\n date:\n payload.date ??\n new Date((payload.timeS ?? nowSeconds) * 1000)\n .toISOString()\n .slice(0, 19)\n .replace(\"T\", \" \"),\n display_name: payload.displayName ?? payload.appIdentifier,\n },\n type: \"Add\",\n };\n const bytes = new TextEncoder().encode(JSON.stringify(model));\n const chunkSize = 176;\n const chunks: Uint8Array[] = [];\n const total = Math.max(1, Math.ceil(bytes.length / chunkSize));\n const packetMessageId = (payload.msgId ?? 0) & 0xff;\n for (let index = 0; index < total; index++) {\n const chunk = bytes.slice(index * chunkSize, (index + 1) * chunkSize);\n const packet = new Uint8Array(4 + chunk.length);\n packet.set([\n G1Command.Notification,\n packetMessageId,\n total & 0xff,\n index & 0xff,\n ]);\n packet.set(chunk, 4);\n chunks.push(packet);\n }\n return chunks;\n}\n\nexport function encodeBmpTransfer(imageData: Uint8Array): Uint8Array[] {\n const packets: Uint8Array[] = [];\n const packetSize = 194;\n for (\n let offset = 0, seq = 0;\n offset < imageData.length;\n offset += packetSize, seq++\n ) {\n const chunk = imageData.slice(offset, offset + packetSize);\n const prefix =\n seq === 0\n ? [G1Command.BmpData, seq & 0xff, 0x00, 0x1c, 0x00, 0x00]\n : [G1Command.BmpData, seq & 0xff];\n const packet = new Uint8Array(prefix.length + chunk.length);\n packet.set(prefix);\n packet.set(chunk, prefix.length);\n packets.push(packet);\n }\n packets.push(Uint8Array.from([G1Command.BmpEnd, 0x0d, 0x0e]));\n const crcInput = new Uint8Array(4 + imageData.length);\n crcInput.set([0x00, 0x1c, 0x00, 0x00]);\n crcInput.set(imageData, 4);\n const crc = crc32(crcInput);\n packets.push(\n Uint8Array.from([\n G1Command.BmpCrc,\n (crc >>> 24) & 0xff,\n (crc >>> 16) & 0xff,\n (crc >>> 8) & 0xff,\n crc & 0xff,\n ]),\n );\n return packets;\n}\n\nexport function encodeG1MonochromeBmp(\n pixels: ArrayLike<number> | Uint8Array,\n options: { width?: number; height?: number; threshold?: number } = {},\n): Uint8Array {\n const width = options.width ?? G1_BMP.width;\n const height = options.height ?? G1_BMP.height;\n const threshold = options.threshold ?? 128;\n if (!Number.isInteger(width) || width <= 0) {\n throw new RangeError(\"BMP width must be a positive integer\");\n }\n if (!Number.isInteger(height) || height <= 0) {\n throw new RangeError(\"BMP height must be a positive integer\");\n }\n const expectedPixels = width * height;\n if (pixels.length !== expectedPixels) {\n throw new RangeError(\n `Expected ${expectedPixels} monochrome pixels, got ${pixels.length}`,\n );\n }\n\n const rowStride = Math.ceil(width / 32) * 4;\n const pixelDataSize = rowStride * height;\n const pixelOffset = 14 + 40 + 8;\n const fileSize = pixelOffset + pixelDataSize;\n const out = new Uint8Array(fileSize);\n const view = new DataView(out.buffer);\n\n out.set([0x42, 0x4d], 0);\n view.setUint32(2, fileSize, true);\n view.setUint32(10, pixelOffset, true);\n view.setUint32(14, 40, true);\n view.setInt32(18, width, true);\n view.setInt32(22, height, true);\n view.setUint16(26, 1, true);\n view.setUint16(28, 1, true);\n view.setUint32(34, pixelDataSize, true);\n view.setUint32(46, 2, true);\n view.setUint32(50, 2, true);\n out.set([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00], 54);\n\n for (let y = 0; y < height; y++) {\n const sourceY = height - 1 - y;\n const rowOffset = pixelOffset + y * rowStride;\n for (let x = 0; x < width; x++) {\n const source = pixels[sourceY * width + x] ?? 0;\n if (source < threshold) continue;\n out[rowOffset + (x >> 3)] |= 0x80 >> (x & 0x07);\n }\n }\n return out;\n}\n\nexport function parseG1Notification(\n side: GlassSide,\n data: Uint8Array,\n): G1Event {\n const command = data[0];\n if (command === G1Command.StartAi) {\n const code = data[1];\n const state = classifyStateCode(code);\n return {\n side,\n raw: data,\n type: \"state\",\n code,\n label: state?.label ?? `unknown_0x${code?.toString(16)}`,\n stateCategory: state?.category,\n stateName: state?.name,\n };\n }\n if (command === G1Command.OpenMic) {\n const responseStatus = data.length >= 3 ? data[1] : undefined;\n const requested = data[data.length - 1];\n const responseOk =\n responseStatus === undefined ||\n responseStatus === G1ResponseStatus.Success;\n const micRequested = requested === G1MicStatus.Enable;\n return {\n side,\n raw: data,\n type: \"mic-response\",\n micEnabled: responseOk ? micRequested : !micRequested,\n micRequested,\n responseStatus,\n responseOk,\n code: requested,\n label:\n responseOk && micRequested\n ? \"mic_enabled\"\n : responseOk\n ? \"mic_disabled\"\n : \"mic_failed\",\n };\n }\n if (command === G1Command.ReceiveMicData) {\n return {\n side,\n raw: data,\n type: \"mic-data\",\n sequence: data[1],\n audioData: data.slice(2),\n audioEncoding: \"lc3\",\n label: \"mic_data\",\n };\n }\n if (command === G1Command.Init || command === G1Command.RightInit) {\n return {\n side,\n raw: data,\n type: \"init\",\n code: data[1],\n label: command === G1Command.RightInit ? \"right_init\" : \"init\",\n };\n }\n if (command === G1Command.SendResult) {\n return parseDisplayResult(side, data);\n }\n if (command === G1Command.Notification) {\n return parseNotificationChunk(side, data);\n }\n if (command === G1Command.QuickNote) {\n return parseVoiceNoteList(side, data);\n }\n if (\n command === G1Command.Note &&\n data.length >= 11 &&\n data[4] === G1VoiceNoteSubCommand.RequestAudioData\n ) {\n const totalPackets = readUint16LE(data, 5);\n const currentPacket = readUint16LE(data, 7);\n const noteIndex = Math.max(0, (data[9] ?? 1) - 1);\n return {\n side,\n raw: data,\n type: \"voice-note-audio\",\n syncId: data[3],\n subcommand: data[4],\n totalPackets,\n currentPacket,\n noteIndex,\n sequence: currentPacket,\n audioData: data.slice(10),\n audioEncoding: \"lc3\",\n label: \"voice_note_audio\",\n };\n }\n if (command === G1Command.Dashboard) {\n const code = data[1];\n return {\n side,\n raw: data,\n type: \"dashboard\",\n code,\n label: `dashboard_0x${code?.toString(16).padStart(2, \"0\")}`,\n };\n }\n if (command === G1Command.GetSerial) {\n const serialNumber = new TextDecoder()\n .decode(data.slice(2, 18))\n .replace(/\\0+$/g, \"\");\n return {\n side,\n raw: data,\n type: \"serial\",\n code: data[1],\n responseStatus: data[1],\n responseOk: data[1] === undefined || data[1] === G1ResponseStatus.Success,\n serialNumber,\n label: \"serial_number\",\n };\n }\n if (command === G1Command.Heartbeat) {\n return { side, raw: data, type: \"heartbeat\", label: \"heartbeat\" };\n }\n if (command === G1Command.Battery) {\n return parseBatteryStatus(side, data);\n }\n if (command === 0x03) {\n return {\n side,\n raw: data,\n type: \"response\",\n code: data[1],\n label: \"response\",\n };\n }\n if (command === 0x04) {\n return {\n side,\n raw: data,\n type: \"error\",\n code: data[1],\n label: `error_0x${data[1]?.toString(16).padStart(2, \"0\")}`,\n };\n }\n return {\n side,\n raw: data,\n type: \"unknown\",\n code: command,\n label: `unknown_0x${command?.toString(16)}`,\n };\n}\n\nfunction parseBatteryStatus(side: GlassSide, data: Uint8Array): G1Event {\n if (data.length < 6 || data[1] !== 0x66) {\n return {\n side,\n raw: data,\n type: \"battery-status\",\n responseStatus: data[1],\n responseOk: false,\n label: \"battery_status_invalid\",\n };\n }\n return {\n side,\n raw: data,\n type: \"battery-status\",\n responseStatus: data[1],\n responseOk: true,\n batteryPercent: data[2],\n batteryFlags: data[3],\n batteryVoltageMv: (((data[5] ?? 0) << 8) | (data[4] ?? 0)) / 10,\n label: \"battery_status\",\n };\n}\n\nfunction parseDisplayResult(side: GlassSide, data: Uint8Array): G1Event {\n if (data.length < 9) {\n return {\n side,\n raw: data,\n type: \"display-result\",\n label: \"display_result_invalid\",\n };\n }\n const textBytes = data.slice(9);\n return {\n side,\n raw: data,\n type: \"display-result\",\n displaySeq: data[1],\n totalPackages: data[2],\n currentPackage: data[3],\n screenStatus: data[4],\n charPosition: readUint16BE(data, 5),\n pageNumber: data[7],\n maxPages: data[8],\n text: new TextDecoder().decode(textBytes),\n label: \"display_result\",\n };\n}\n\nfunction parseNotificationChunk(side: GlassSide, data: Uint8Array): G1Event {\n if (data.length < 4) {\n return {\n side,\n raw: data,\n type: \"notification\",\n label: \"notification_invalid\",\n };\n }\n const notificationChunk = data.slice(4);\n return {\n side,\n raw: data,\n type: \"notification\",\n notificationId: data[1],\n totalPackages: data[2],\n currentPackage: data[3],\n notificationChunk,\n text: new TextDecoder().decode(notificationChunk),\n label: \"notification\",\n };\n}\n\nfunction parseVoiceNoteList(side: GlassSide, data: Uint8Array): G1Event {\n const length = readUint16LE(data, 1);\n const syncId = data[3];\n const subcommand = data[4];\n if (\n data.length < 6 ||\n subcommand !== G1VoiceNoteSubCommand.RequestAudioInfo\n ) {\n return {\n side,\n raw: data,\n type: \"voice-note-list\",\n syncId,\n subcommand,\n voiceNotes: [],\n label: \"voice_note_list_invalid\",\n };\n }\n const noteCount = data[5] ?? 0;\n const expectedLength = 6 + noteCount * 9;\n const boundedLength = Math.min(data.length, Math.max(length, expectedLength));\n const voiceNotes: G1VoiceNoteEntry[] = [];\n for (\n let offset = 6;\n offset + 8 < boundedLength && voiceNotes.length < noteCount;\n offset += 9\n ) {\n voiceNotes.push({\n index: data[offset],\n timestamp: readUint32LE(data, offset + 1),\n crc: readUint32LE(data, offset + 5),\n });\n }\n return {\n side,\n raw: data,\n type: \"voice-note-list\",\n syncId,\n subcommand,\n voiceNotes,\n label: \"voice_note_list\",\n };\n}\n\nexport function pcm16ToFloat32(bytes: Uint8Array): Float32Array {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const out = new Float32Array(Math.floor(bytes.byteLength / 2));\n for (let i = 0; i < out.length; i++)\n out[i] = view.getInt16(i * 2, true) / 32768;\n return out;\n}\n\nfunction validateNoteNumber(noteNumber: number): void {\n if (!Number.isInteger(noteNumber) || noteNumber < 1 || noteNumber > 4) {\n throw new RangeError(\"Note number must be an integer between 1 and 4\");\n }\n}\n\nfunction validateVoiceNoteIndex(noteIndex: number): void {\n if (!Number.isInteger(noteIndex) || noteIndex < 0 || noteIndex > 255) {\n throw new RangeError(\n \"G1 voice note index must be an integer from 0 to 255\",\n );\n }\n}\n\nfunction validateBitPlanes(\n image: ArrayLike<number>,\n overlay: ArrayLike<number>,\n expectedLength: number,\n label: string,\n): void {\n if (image.length !== expectedLength || overlay.length !== expectedLength) {\n throw new RangeError(\n `Expected ${expectedLength} bits for ${label} and overlay`,\n );\n }\n}\n\nfunction runLengthEncodeBits(data: number[]): number[] {\n if (data.length === 0) return [];\n const encoded: number[] = [];\n let current = data[0] ? 1 : 0;\n let count = 1;\n for (let index = 1; index < data.length; index++) {\n const bit = data[index] ? 1 : 0;\n if (bit === current && count < 255) {\n count += 1;\n continue;\n }\n encoded.push(count, current);\n current = bit;\n count = 1;\n }\n encoded.push(count, current);\n return encoded;\n}\n\nfunction encodeNavigationImagePackets(\n bytes: number[],\n partType: number,\n startSeqId: number,\n includeExtraZero: boolean,\n): Uint8Array[] {\n const maxPayload = 185;\n const packetCount = Math.max(1, Math.ceil(bytes.length / maxPayload));\n const packets: Uint8Array[] = [];\n let seqId = startSeqId & 0xff;\n for (let index = 0; index < packetCount; index++) {\n const chunk = bytes.slice(index * maxPayload, (index + 1) * maxPayload);\n const part = [\n 0x00,\n seqId,\n partType,\n packetCount & 0xff,\n 0x00,\n (index + 1) & 0xff,\n 0x00,\n ...(includeExtraZero ? [0x00] : []),\n ...chunk.map((byte) => byte & 0xff),\n ];\n packets.push(\n Uint8Array.from([\n G1Command.Navigation,\n (part.length + 2) & 0xff,\n ...part,\n ]),\n );\n seqId = (seqId + 1) & 0xff;\n }\n return packets;\n}\n\nfunction readUint16LE(data: Uint8Array, offset: number): number {\n return (data[offset] ?? 0) | ((data[offset + 1] ?? 0) << 8);\n}\n\nfunction readUint16BE(data: Uint8Array, offset: number): number {\n return ((data[offset] ?? 0) << 8) | (data[offset + 1] ?? 0);\n}\n\nfunction readUint32LE(data: Uint8Array, offset: number): number {\n return (\n ((data[offset] ?? 0) |\n ((data[offset + 1] ?? 0) << 8) |\n ((data[offset + 2] ?? 0) << 16) |\n ((data[offset + 3] ?? 0) << 24)) >>>\n 0\n );\n}\n\nfunction crc32(bytes: Uint8Array): number {\n let crc = 0xffffffff;\n for (const byte of bytes) {\n crc ^= byte;\n for (let bit = 0; bit < 8; bit++) {\n crc = crc & 1 ? (crc >>> 1) ^ 0xedb88320 : crc >>> 1;\n }\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n"],"mappings":"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","names":["G1Command","G1DashboardLayout","G1WeatherIcon","G1TemperatureUnit","G1TimeFormat","G1NavigationTurn","G1TranslateLanguage","G1SubCommand","G1MicStatus","G1ResponseStatus","G1ScreenAction","G1AiStatus","G1TextStatus","G1SilentModeStatus","G1DashboardState","G1GlassesWearStatus","G1VoiceNoteSubCommand","G1InteractionCode"]}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
export type XRDeviceType = "quest3" | "xreal" | "even-realities" | "simulator";
|
|
2
|
+
/** View panel state reported back from the XR device */
|
|
3
|
+
export interface XRViewPanelState {
|
|
4
|
+
viewId: string;
|
|
5
|
+
active: boolean;
|
|
6
|
+
width?: number;
|
|
7
|
+
height?: number;
|
|
8
|
+
}
|
|
9
|
+
export type XRClientControl = {
|
|
10
|
+
type: "hello";
|
|
11
|
+
deviceType: XRDeviceType;
|
|
12
|
+
sessionId: string;
|
|
13
|
+
} | {
|
|
14
|
+
type: "ping";
|
|
15
|
+
} | {
|
|
16
|
+
type: "g1_raw";
|
|
17
|
+
side?: "left" | "right";
|
|
18
|
+
data?: number[];
|
|
19
|
+
base64?: string;
|
|
20
|
+
} | {
|
|
21
|
+
type: "mic_lc3" | "mic_pcm";
|
|
22
|
+
side?: "left" | "right";
|
|
23
|
+
sampleRate?: number;
|
|
24
|
+
sequence?: number;
|
|
25
|
+
lc3?: number[];
|
|
26
|
+
pcm?: number[];
|
|
27
|
+
base64?: string;
|
|
28
|
+
} | {
|
|
29
|
+
type: "view_ready";
|
|
30
|
+
viewId: string;
|
|
31
|
+
} | {
|
|
32
|
+
type: "view_closed";
|
|
33
|
+
viewId: string;
|
|
34
|
+
} | {
|
|
35
|
+
type: "view_event";
|
|
36
|
+
viewId: string;
|
|
37
|
+
event: string;
|
|
38
|
+
payload?: unknown;
|
|
39
|
+
};
|
|
40
|
+
export interface XRAudioHeader {
|
|
41
|
+
type: "audio";
|
|
42
|
+
ts: number;
|
|
43
|
+
sampleRate: number;
|
|
44
|
+
/** "webm-opus" from MediaRecorder, "pcm-f32" from ScriptProcessor fallback */
|
|
45
|
+
encoding: "webm-opus" | "pcm-f32";
|
|
46
|
+
}
|
|
47
|
+
export interface XRFrameHeader {
|
|
48
|
+
type: "frame";
|
|
49
|
+
ts: number;
|
|
50
|
+
width: number;
|
|
51
|
+
height: number;
|
|
52
|
+
format: "jpeg" | "webp";
|
|
53
|
+
pose?: {
|
|
54
|
+
position: {
|
|
55
|
+
x: number;
|
|
56
|
+
y: number;
|
|
57
|
+
z: number;
|
|
58
|
+
};
|
|
59
|
+
orientation: {
|
|
60
|
+
x: number;
|
|
61
|
+
y: number;
|
|
62
|
+
z: number;
|
|
63
|
+
w: number;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export type XRBinaryHeader = XRAudioHeader | XRFrameHeader;
|
|
68
|
+
/** XR panel sizing options */
|
|
69
|
+
export interface XRPanelConfig {
|
|
70
|
+
/** Panel width relative to default (0.5 = half, 2.0 = double) */
|
|
71
|
+
scale?: number;
|
|
72
|
+
/** Follow mode: billboard | fixed | follow */
|
|
73
|
+
followMode?: "billboard" | "fixed" | "follow";
|
|
74
|
+
/** Distance from camera in metres */
|
|
75
|
+
distance?: number;
|
|
76
|
+
/** Whether to show as full-overlay or floating panel */
|
|
77
|
+
fullscreen?: boolean;
|
|
78
|
+
}
|
|
79
|
+
export type XRServerControl = {
|
|
80
|
+
type: "ready";
|
|
81
|
+
sessionId: string;
|
|
82
|
+
} | {
|
|
83
|
+
type: "transcript";
|
|
84
|
+
text: string;
|
|
85
|
+
final: boolean;
|
|
86
|
+
} | {
|
|
87
|
+
type: "agent_text";
|
|
88
|
+
text: string;
|
|
89
|
+
} | {
|
|
90
|
+
type: "pong";
|
|
91
|
+
}
|
|
92
|
+
/** Open (or bring to front) a view by its registered view id */
|
|
93
|
+
| {
|
|
94
|
+
type: "view_open";
|
|
95
|
+
viewId: string;
|
|
96
|
+
agentBaseUrl: string;
|
|
97
|
+
config?: XRPanelConfig;
|
|
98
|
+
}
|
|
99
|
+
/** Close a specific view panel */
|
|
100
|
+
| {
|
|
101
|
+
type: "view_close";
|
|
102
|
+
viewId: string;
|
|
103
|
+
}
|
|
104
|
+
/** Switch the "active" (foreground) view */
|
|
105
|
+
| {
|
|
106
|
+
type: "view_switch";
|
|
107
|
+
viewId: string;
|
|
108
|
+
}
|
|
109
|
+
/** Resize / reposition the active or named panel */
|
|
110
|
+
| {
|
|
111
|
+
type: "view_resize";
|
|
112
|
+
viewId?: string;
|
|
113
|
+
config: XRPanelConfig;
|
|
114
|
+
}
|
|
115
|
+
/** Send all available views to the device for the launcher */
|
|
116
|
+
| {
|
|
117
|
+
type: "views_catalog";
|
|
118
|
+
views: Array<{
|
|
119
|
+
id: string;
|
|
120
|
+
label: string;
|
|
121
|
+
icon?: string;
|
|
122
|
+
description?: string;
|
|
123
|
+
}>;
|
|
124
|
+
};
|
|
125
|
+
export interface XRTTSAudioHeader {
|
|
126
|
+
type: "tts_audio";
|
|
127
|
+
sampleRate: number;
|
|
128
|
+
channels: number;
|
|
129
|
+
/** encoding of the outbound audio */
|
|
130
|
+
encoding: "mp3" | "wav" | "pcm-f32";
|
|
131
|
+
}
|
|
132
|
+
export declare function encodeBinaryFrame(header: XRBinaryHeader | XRTTSAudioHeader, payload: Uint8Array | Buffer): Buffer;
|
|
133
|
+
export declare function decodeBinaryFrame(data: Buffer): {
|
|
134
|
+
header: XRBinaryHeader | XRTTSAudioHeader;
|
|
135
|
+
payload: Buffer;
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=xr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xr.d.ts","sourceRoot":"","sources":["../../src/protocol/xr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
function encodeBinaryFrame(header, payload) {
|
|
2
|
+
const headerJson = Buffer.from(JSON.stringify(header), "utf8");
|
|
3
|
+
const lenBuf = Buffer.allocUnsafe(4);
|
|
4
|
+
lenBuf.writeUInt32BE(headerJson.length, 0);
|
|
5
|
+
return Buffer.concat([lenBuf, headerJson, payload]);
|
|
6
|
+
}
|
|
7
|
+
function decodeBinaryFrame(data) {
|
|
8
|
+
const headerLen = data.readUInt32BE(0);
|
|
9
|
+
const headerJson = data.subarray(4, 4 + headerLen).toString("utf8");
|
|
10
|
+
const header = JSON.parse(headerJson);
|
|
11
|
+
const payload = data.subarray(4 + headerLen);
|
|
12
|
+
return { header, payload };
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
decodeBinaryFrame,
|
|
16
|
+
encodeBinaryFrame
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=xr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/protocol/xr.ts"],"sourcesContent":["// Binary frame layout:\n// bytes 0–3 : big-endian uint32 — JSON header length\n// bytes 4–N : UTF-8 JSON header\n// bytes N+1… : raw binary payload (audio PCM/Opus, JPEG, etc.)\n//\n// Text frames are JSON control messages (no binary payload).\n\nexport type XRDeviceType = \"quest3\" | \"xreal\" | \"even-realities\" | \"simulator\";\n\n// ── Client → Server (text frames) ──────────────────────────────────────────\n\n/** View panel state reported back from the XR device */\nexport interface XRViewPanelState {\n viewId: string;\n active: boolean;\n width?: number;\n height?: number;\n}\n\nexport type XRClientControl =\n | { type: \"hello\"; deviceType: XRDeviceType; sessionId: string }\n | { type: \"ping\" }\n | {\n type: \"g1_raw\";\n side?: \"left\" | \"right\";\n data?: number[];\n base64?: string;\n }\n | {\n type: \"mic_lc3\" | \"mic_pcm\";\n side?: \"left\" | \"right\";\n sampleRate?: number;\n sequence?: number;\n lc3?: number[];\n pcm?: number[];\n base64?: string;\n }\n | { type: \"view_ready\"; viewId: string }\n | { type: \"view_closed\"; viewId: string }\n | { type: \"view_event\"; viewId: string; event: string; payload?: unknown };\n\n// ── Client → Server (binary frames) ────────────────────────────────────────\n\nexport interface XRAudioHeader {\n type: \"audio\";\n ts: number;\n sampleRate: number;\n /** \"webm-opus\" from MediaRecorder, \"pcm-f32\" from ScriptProcessor fallback */\n encoding: \"webm-opus\" | \"pcm-f32\";\n}\n\nexport interface XRFrameHeader {\n type: \"frame\";\n ts: number;\n width: number;\n height: number;\n format: \"jpeg\" | \"webp\";\n pose?: {\n position: { x: number; y: number; z: number };\n orientation: { x: number; y: number; z: number; w: number };\n };\n}\n\nexport type XRBinaryHeader = XRAudioHeader | XRFrameHeader;\n\n// ── Server → Client (text frames) ──────────────────────────────────────────\n\n/** XR panel sizing options */\nexport interface XRPanelConfig {\n /** Panel width relative to default (0.5 = half, 2.0 = double) */\n scale?: number;\n /** Follow mode: billboard | fixed | follow */\n followMode?: \"billboard\" | \"fixed\" | \"follow\";\n /** Distance from camera in metres */\n distance?: number;\n /** Whether to show as full-overlay or floating panel */\n fullscreen?: boolean;\n}\n\nexport type XRServerControl =\n | { type: \"ready\"; sessionId: string }\n | { type: \"transcript\"; text: string; final: boolean }\n | { type: \"agent_text\"; text: string }\n | { type: \"pong\" }\n // ── View commands ────────────────────────────────────────────────────────\n /** Open (or bring to front) a view by its registered view id */\n | {\n type: \"view_open\";\n viewId: string;\n agentBaseUrl: string;\n config?: XRPanelConfig;\n }\n /** Close a specific view panel */\n | { type: \"view_close\"; viewId: string }\n /** Switch the \"active\" (foreground) view */\n | { type: \"view_switch\"; viewId: string }\n /** Resize / reposition the active or named panel */\n | { type: \"view_resize\"; viewId?: string; config: XRPanelConfig }\n /** Send all available views to the device for the launcher */\n | {\n type: \"views_catalog\";\n views: Array<{\n id: string;\n label: string;\n icon?: string;\n description?: string;\n }>;\n };\n\n// ── Server → Client (binary frames) ────────────────────────────────────────\n\nexport interface XRTTSAudioHeader {\n type: \"tts_audio\";\n sampleRate: number;\n channels: number;\n /** encoding of the outbound audio */\n encoding: \"mp3\" | \"wav\" | \"pcm-f32\";\n}\n\n// ── Framing helpers ─────────────────────────────────────────────────────────\n\nexport function encodeBinaryFrame(\n header: XRBinaryHeader | XRTTSAudioHeader,\n payload: Uint8Array | Buffer,\n): Buffer {\n const headerJson = Buffer.from(JSON.stringify(header), \"utf8\");\n const lenBuf = Buffer.allocUnsafe(4);\n lenBuf.writeUInt32BE(headerJson.length, 0);\n return Buffer.concat([lenBuf, headerJson, payload]);\n}\n\nexport function decodeBinaryFrame(data: Buffer): {\n header: XRBinaryHeader | XRTTSAudioHeader;\n payload: Buffer;\n} {\n const headerLen = data.readUInt32BE(0);\n const headerJson = data.subarray(4, 4 + headerLen).toString(\"utf8\");\n const header = JSON.parse(headerJson) as XRBinaryHeader | XRTTSAudioHeader;\n const payload = data.subarray(4 + headerLen);\n return { header, payload };\n}\n"],"mappings":"AAyHO,SAAS,kBACd,QACA,SACQ;AACR,QAAM,aAAa,OAAO,KAAK,KAAK,UAAU,MAAM,GAAG,MAAM;AAC7D,QAAM,SAAS,OAAO,YAAY,CAAC;AACnC,SAAO,cAAc,WAAW,QAAQ,CAAC;AACzC,SAAO,OAAO,OAAO,CAAC,QAAQ,YAAY,OAAO,CAAC;AACpD;AAEO,SAAS,kBAAkB,MAGhC;AACA,QAAM,YAAY,KAAK,aAAa,CAAC;AACrC,QAAM,aAAa,KAAK,SAAS,GAAG,IAAI,SAAS,EAAE,SAAS,MAAM;AAClE,QAAM,SAAS,KAAK,MAAM,UAAU;AACpC,QAAM,UAAU,KAAK,SAAS,IAAI,SAAS;AAC3C,SAAO,EAAE,QAAQ,QAAQ;AAC3B;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facewear-context.d.ts","sourceRoot":"","sources":["../../src/providers/facewear-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,QAAQ,EAIT,MAAM,eAAe,CAAC;AAQvB,eAAO,MAAM,uBAAuB,EAAE,QAmErC,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { SMARTGLASSES_SERVICE_NAME } from "../services/smartglasses-service.js";
|
|
2
|
+
import {
|
|
3
|
+
XR_SERVICE_TYPE
|
|
4
|
+
} from "../services/xr-session-service.js";
|
|
5
|
+
const facewearContextProvider = {
|
|
6
|
+
name: "xrContext",
|
|
7
|
+
description: "Provides context about connected XR headsets and smartglasses (Quest 3, XReal, Even Realities, Apple Vision Pro)",
|
|
8
|
+
get: async (runtime, _message, _state) => {
|
|
9
|
+
const xrSvc = runtime.getService(XR_SERVICE_TYPE);
|
|
10
|
+
const sgSvc = runtime.getService(
|
|
11
|
+
SMARTGLASSES_SERVICE_NAME
|
|
12
|
+
);
|
|
13
|
+
const hasXR = xrSvc?.hasActiveConnections() ?? false;
|
|
14
|
+
const hasSmartglasses = sgSvc?.getStatus().connected ?? false;
|
|
15
|
+
if (!hasXR && !hasSmartglasses) return { text: "" };
|
|
16
|
+
const lines = [];
|
|
17
|
+
const values = {};
|
|
18
|
+
if (hasXR && xrSvc) {
|
|
19
|
+
const conns = xrSvc.getConnections();
|
|
20
|
+
const deviceList = conns.map((c) => {
|
|
21
|
+
const hasFrame = xrSvc.getVisionPipeline().hasRecentFrame(c.id);
|
|
22
|
+
return `${c.deviceType}${hasFrame ? " (camera active)" : ""}`;
|
|
23
|
+
}).join(", ");
|
|
24
|
+
lines.push(`[XR devices connected: ${deviceList}]`);
|
|
25
|
+
lines.push(
|
|
26
|
+
`[Audio streaming active \u2014 the user is speaking to you via their headset microphone.]`
|
|
27
|
+
);
|
|
28
|
+
lines.push(
|
|
29
|
+
`[Your text responses will be spoken aloud through the headset via TTS.]`
|
|
30
|
+
);
|
|
31
|
+
lines.push(
|
|
32
|
+
`[Use XR_QUERY_VISION to describe what the user's camera sees.]`
|
|
33
|
+
);
|
|
34
|
+
values.xrConnected = true;
|
|
35
|
+
values.xrDevices = conns.map((c) => c.deviceType);
|
|
36
|
+
values.xrConnectionCount = conns.length;
|
|
37
|
+
}
|
|
38
|
+
if (hasSmartglasses && sgSvc) {
|
|
39
|
+
const status = sgSvc.getStatus();
|
|
40
|
+
lines.push(
|
|
41
|
+
`[Smartglasses connected: ${status.transport ?? "unknown transport"}]`
|
|
42
|
+
);
|
|
43
|
+
if (status.microphoneEnabled) {
|
|
44
|
+
lines.push(`[Smartglasses microphone is active.]`);
|
|
45
|
+
}
|
|
46
|
+
values.smartglassesConnected = true;
|
|
47
|
+
values.smartglassesTransport = status.transport;
|
|
48
|
+
values.smartgrassesMicEnabled = status.microphoneEnabled;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
text: lines.join("\n"),
|
|
52
|
+
values
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
export {
|
|
57
|
+
facewearContextProvider
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=facewear-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/providers/facewear-context.ts"],"sourcesContent":["import type {\n IAgentRuntime,\n Memory,\n Provider,\n ProviderResult,\n ProviderValue,\n State,\n} from \"@elizaos/core\";\nimport type { SmartglassesService } from \"../services/smartglasses-service.js\";\nimport { SMARTGLASSES_SERVICE_NAME } from \"../services/smartglasses-service.js\";\nimport {\n XR_SERVICE_TYPE,\n type XRSessionService,\n} from \"../services/xr-session-service.js\";\n\nexport const facewearContextProvider: Provider = {\n name: \"xrContext\",\n description:\n \"Provides context about connected XR headsets and smartglasses (Quest 3, XReal, Even Realities, Apple Vision Pro)\",\n\n get: async (\n runtime: IAgentRuntime,\n _message: Memory,\n _state: State,\n ): Promise<ProviderResult> => {\n const xrSvc = runtime.getService<XRSessionService>(XR_SERVICE_TYPE);\n const sgSvc = runtime.getService<SmartglassesService>(\n SMARTGLASSES_SERVICE_NAME,\n );\n\n const hasXR = xrSvc?.hasActiveConnections() ?? false;\n const hasSmartglasses = sgSvc?.getStatus().connected ?? false;\n\n if (!hasXR && !hasSmartglasses) return { text: \"\" };\n\n const lines: string[] = [];\n const values: Record<string, ProviderValue> = {};\n\n if (hasXR && xrSvc) {\n const conns = xrSvc.getConnections();\n const deviceList = conns\n .map((c) => {\n const hasFrame = xrSvc.getVisionPipeline().hasRecentFrame(c.id);\n return `${c.deviceType}${hasFrame ? \" (camera active)\" : \"\"}`;\n })\n .join(\", \");\n\n lines.push(`[XR devices connected: ${deviceList}]`);\n lines.push(\n `[Audio streaming active — the user is speaking to you via their headset microphone.]`,\n );\n lines.push(\n `[Your text responses will be spoken aloud through the headset via TTS.]`,\n );\n lines.push(\n `[Use XR_QUERY_VISION to describe what the user's camera sees.]`,\n );\n\n values.xrConnected = true;\n values.xrDevices = conns.map((c) => c.deviceType);\n values.xrConnectionCount = conns.length;\n }\n\n if (hasSmartglasses && sgSvc) {\n const status = sgSvc.getStatus();\n lines.push(\n `[Smartglasses connected: ${status.transport ?? \"unknown transport\"}]`,\n );\n if (status.microphoneEnabled) {\n lines.push(`[Smartglasses microphone is active.]`);\n }\n\n values.smartglassesConnected = true;\n values.smartglassesTransport = status.transport;\n values.smartgrassesMicEnabled = status.microphoneEnabled;\n }\n\n return {\n text: lines.join(\"\\n\"),\n values,\n };\n },\n};\n"],"mappings":"AASA,SAAS,iCAAiC;AAC1C;AAAA,EACE;AAAA,OAEK;AAEA,MAAM,0BAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,aACE;AAAA,EAEF,KAAK,OACH,SACA,UACA,WAC4B;AAC5B,UAAM,QAAQ,QAAQ,WAA6B,eAAe;AAClE,UAAM,QAAQ,QAAQ;AAAA,MACpB;AAAA,IACF;AAEA,UAAM,QAAQ,OAAO,qBAAqB,KAAK;AAC/C,UAAM,kBAAkB,OAAO,UAAU,EAAE,aAAa;AAExD,QAAI,CAAC,SAAS,CAAC,gBAAiB,QAAO,EAAE,MAAM,GAAG;AAElD,UAAM,QAAkB,CAAC;AACzB,UAAM,SAAwC,CAAC;AAE/C,QAAI,SAAS,OAAO;AAClB,YAAM,QAAQ,MAAM,eAAe;AACnC,YAAM,aAAa,MAChB,IAAI,CAAC,MAAM;AACV,cAAM,WAAW,MAAM,kBAAkB,EAAE,eAAe,EAAE,EAAE;AAC9D,eAAO,GAAG,EAAE,UAAU,GAAG,WAAW,qBAAqB,EAAE;AAAA,MAC7D,CAAC,EACA,KAAK,IAAI;AAEZ,YAAM,KAAK,0BAA0B,UAAU,GAAG;AAClD,YAAM;AAAA,QACJ;AAAA,MACF;AACA,YAAM;AAAA,QACJ;AAAA,MACF;AACA,YAAM;AAAA,QACJ;AAAA,MACF;AAEA,aAAO,cAAc;AACrB,aAAO,YAAY,MAAM,IAAI,CAAC,MAAM,EAAE,UAAU;AAChD,aAAO,oBAAoB,MAAM;AAAA,IACnC;AAEA,QAAI,mBAAmB,OAAO;AAC5B,YAAM,SAAS,MAAM,UAAU;AAC/B,YAAM;AAAA,QACJ,4BAA4B,OAAO,aAAa,mBAAmB;AAAA,MACrE;AACA,UAAI,OAAO,mBAAmB;AAC5B,cAAM,KAAK,sCAAsC;AAAA,MACnD;AAEA,aAAO,wBAAwB;AAC/B,aAAO,wBAAwB,OAAO;AACtC,aAAO,yBAAyB,OAAO;AAAA,IACzC;AAEA,WAAO;AAAA,MACL,MAAM,MAAM,KAAK,IAAI;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smartglasses-status.d.ts","sourceRoot":"","sources":["../../src/providers/smartglasses-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAO9C,eAAO,MAAM,0BAA0B,EAAE,QAyCxC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { getSmartglassesService } from "../services/smartglasses-service.js";
|
|
2
|
+
import {
|
|
3
|
+
formatConnectedLensesForProvider,
|
|
4
|
+
setupSummaryForStatus
|
|
5
|
+
} from "../status-format.js";
|
|
6
|
+
const smartglassesStatusProvider = {
|
|
7
|
+
name: "smartglassesStatus",
|
|
8
|
+
description: "Current Even Realities smartglasses connection, microphone, event, and audio status.",
|
|
9
|
+
get: async (runtime) => {
|
|
10
|
+
const service = getSmartglassesService(runtime);
|
|
11
|
+
if (!service) {
|
|
12
|
+
return {
|
|
13
|
+
text: "Smartglasses service not loaded.",
|
|
14
|
+
values: { available: false }
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const status = service.getStatus();
|
|
18
|
+
const setup = setupSummaryForStatus(status);
|
|
19
|
+
return {
|
|
20
|
+
text: `Smartglasses: connected=${status.connected}, transport=${status.transport ?? "none"}, lenses=${formatConnectedLensesForProvider(status.connectedLenses)}, microphone=${status.microphoneEnabled ? "enabled" : "disabled"}, heartbeat=${status.heartbeatRunning ? "running" : "stopped"}, lastEvent=${status.lastEvent?.label ?? "none"}, physical=${status.physicalState ?? "none"}, battery=${status.batteryState ?? "none"}, batteryLevels=${formatBatteryLevels(status.batteryLevels)}, device=${status.deviceState ?? "none"}, setup=${setup.setupHint ?? "none"}, wholeHeadset=${setup.wholeHeadsetConnected}, wearingReady=${setup.wearingReady}, physicalBlocker=${setup.physicalBlocker ?? "none"}, serial=${status.lastSerialNumber ?? "none"}, wifi=${status.wifiAvailable ? "available" : "unavailable"}, wifiStatus=${status.lastWifiStatus?.status ?? "none"}, transcript=${status.lastTranscript ?? "none"}, audioChunks=${status.audioChunksReceived}, audioEncoding=${status.lastAudioEncoding ?? "none"}, audioSequence=${status.lastAudioSequence ?? "none"}, audioSequenceGaps=${status.audioSequenceGaps}`,
|
|
21
|
+
values: { ...status, setup }
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
function formatBatteryLevels(levels) {
|
|
26
|
+
const left = levels.left === void 0 ? "unknown" : `${levels.left}%`;
|
|
27
|
+
const right = levels.right === void 0 ? "unknown" : `${levels.right}%`;
|
|
28
|
+
return `left:${left} right:${right}`;
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
smartglassesStatusProvider
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=smartglasses-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/providers/smartglasses-status.ts"],"sourcesContent":["import type { Provider } from \"@elizaos/core\";\nimport { getSmartglassesService } from \"../services/smartglasses-service.js\";\nimport {\n formatConnectedLensesForProvider,\n setupSummaryForStatus,\n} from \"../status-format.js\";\n\nexport const smartglassesStatusProvider: Provider = {\n name: \"smartglassesStatus\",\n description:\n \"Current Even Realities smartglasses connection, microphone, event, and audio status.\",\n get: async (runtime) => {\n const service = getSmartglassesService(runtime);\n if (!service) {\n return {\n text: \"Smartglasses service not loaded.\",\n values: { available: false },\n };\n }\n const status = service.getStatus();\n const setup = setupSummaryForStatus(status);\n return {\n text:\n `Smartglasses: connected=${status.connected}, ` +\n `transport=${status.transport ?? \"none\"}, ` +\n `lenses=${formatConnectedLensesForProvider(status.connectedLenses)}, ` +\n `microphone=${status.microphoneEnabled ? \"enabled\" : \"disabled\"}, ` +\n `heartbeat=${status.heartbeatRunning ? \"running\" : \"stopped\"}, ` +\n `lastEvent=${status.lastEvent?.label ?? \"none\"}, ` +\n `physical=${status.physicalState ?? \"none\"}, ` +\n `battery=${status.batteryState ?? \"none\"}, ` +\n `batteryLevels=${formatBatteryLevels(status.batteryLevels)}, ` +\n `device=${status.deviceState ?? \"none\"}, ` +\n `setup=${setup.setupHint ?? \"none\"}, ` +\n `wholeHeadset=${setup.wholeHeadsetConnected}, ` +\n `wearingReady=${setup.wearingReady}, ` +\n `physicalBlocker=${setup.physicalBlocker ?? \"none\"}, ` +\n `serial=${status.lastSerialNumber ?? \"none\"}, ` +\n `wifi=${status.wifiAvailable ? \"available\" : \"unavailable\"}, ` +\n `wifiStatus=${status.lastWifiStatus?.status ?? \"none\"}, ` +\n `transcript=${status.lastTranscript ?? \"none\"}, ` +\n `audioChunks=${status.audioChunksReceived}, ` +\n `audioEncoding=${status.lastAudioEncoding ?? \"none\"}, ` +\n `audioSequence=${status.lastAudioSequence ?? \"none\"}, ` +\n `audioSequenceGaps=${status.audioSequenceGaps}`,\n values: { ...status, setup },\n };\n },\n};\n\nfunction formatBatteryLevels(\n levels: Partial<Record<\"left\" | \"right\", number>>,\n): string {\n const left = levels.left === undefined ? \"unknown\" : `${levels.left}%`;\n const right = levels.right === undefined ? \"unknown\" : `${levels.right}%`;\n return `left:${left} right:${right}`;\n}\n"],"mappings":"AACA,SAAS,8BAA8B;AACvC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEA,MAAM,6BAAuC;AAAA,EAClD,MAAM;AAAA,EACN,aACE;AAAA,EACF,KAAK,OAAO,YAAY;AACtB,UAAM,UAAU,uBAAuB,OAAO;AAC9C,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,EAAE,WAAW,MAAM;AAAA,MAC7B;AAAA,IACF;AACA,UAAM,SAAS,QAAQ,UAAU;AACjC,UAAM,QAAQ,sBAAsB,MAAM;AAC1C,WAAO;AAAA,MACL,MACE,2BAA2B,OAAO,SAAS,eAC9B,OAAO,aAAa,MAAM,YAC7B,iCAAiC,OAAO,eAAe,CAAC,gBACpD,OAAO,oBAAoB,YAAY,UAAU,eAClD,OAAO,mBAAmB,YAAY,SAAS,eAC/C,OAAO,WAAW,SAAS,MAAM,cAClC,OAAO,iBAAiB,MAAM,aAC/B,OAAO,gBAAgB,MAAM,mBACvB,oBAAoB,OAAO,aAAa,CAAC,YAChD,OAAO,eAAe,MAAM,WAC7B,MAAM,aAAa,MAAM,kBAClB,MAAM,qBAAqB,kBAC3B,MAAM,YAAY,qBACf,MAAM,mBAAmB,MAAM,YACxC,OAAO,oBAAoB,MAAM,UACnC,OAAO,gBAAgB,cAAc,aAAa,gBAC5C,OAAO,gBAAgB,UAAU,MAAM,gBACvC,OAAO,kBAAkB,MAAM,iBAC9B,OAAO,mBAAmB,mBACxB,OAAO,qBAAqB,MAAM,mBAClC,OAAO,qBAAqB,MAAM,uBAC9B,OAAO,iBAAiB;AAAA,MAC/C,QAAQ,EAAE,GAAG,QAAQ,MAAM;AAAA,IAC7B;AAAA,EACF;AACF;AAEA,SAAS,oBACP,QACQ;AACR,QAAM,OAAO,OAAO,SAAS,SAAY,YAAY,GAAG,OAAO,IAAI;AACnE,QAAM,QAAQ,OAAO,UAAU,SAAY,YAAY,GAAG,OAAO,KAAK;AACtE,SAAO,QAAQ,IAAI,UAAU,KAAK;AACpC;","names":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register the facewear + smartglasses views for terminal rendering.
|
|
3
|
+
*
|
|
4
|
+
* The agent terminal mounts plugin views by id from the `@elizaos/tui` terminal
|
|
5
|
+
* registry. This makes each view's `tui` modality render for real in the
|
|
6
|
+
* terminal (the unified {@link FacewearSpatialView} / {@link
|
|
7
|
+
* SmartglassesSpatialView}) rather than only navigating a GUI shell. A
|
|
8
|
+
* module-level snapshot per view lets a host push live data; with nothing paired
|
|
9
|
+
* each defaults to a sensible empty/disconnected state.
|
|
10
|
+
*/
|
|
11
|
+
import { type FacewearSnapshot } from "./components/FacewearSpatialView.js";
|
|
12
|
+
import { type SmartglassesSnapshot } from "./components/SmartglassesSpatialView.js";
|
|
13
|
+
/** Update the snapshot the registered facewear terminal view renders from. */
|
|
14
|
+
export declare function setFacewearTerminalSnapshot(next: FacewearSnapshot): void;
|
|
15
|
+
/** Register the facewear terminal view; returns an unregister function. */
|
|
16
|
+
export declare function registerFacewearTerminalView(): () => void;
|
|
17
|
+
/** Update the snapshot the registered smartglasses terminal view renders from. */
|
|
18
|
+
export declare function setSmartglassesTerminalSnapshot(next: SmartglassesSnapshot): void;
|
|
19
|
+
/** Register the smartglasses terminal view; returns an unregister function. */
|
|
20
|
+
export declare function registerSmartglassesTerminalView(): () => void;
|
|
21
|
+
//# sourceMappingURL=register-terminal-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-terminal-view.d.ts","sourceRoot":"","sources":["../src/register-terminal-view.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,KAAK,oBAAoB,EAE1B,MAAM,0CAA0C,CAAC;AA2ClD,8EAA8E;AAC9E,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAExE;AAED,2EAA2E;AAC3E,wBAAgB,4BAA4B,IAAI,MAAM,IAAI,CAIzD;AAED,kFAAkF;AAClF,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,oBAAoB,GACzB,IAAI,CAEN;AAED,+EAA+E;AAC/E,wBAAgB,gCAAgC,IAAI,MAAM,IAAI,CAI7D"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { registerSpatialTerminalView } from "@elizaos/ui/spatial/tui";
|
|
2
|
+
import { createElement } from "react";
|
|
3
|
+
import {
|
|
4
|
+
EMPTY_FACEWEAR_SNAPSHOT,
|
|
5
|
+
FacewearSpatialView
|
|
6
|
+
} from "./components/FacewearSpatialView.js";
|
|
7
|
+
import {
|
|
8
|
+
SmartglassesSpatialView
|
|
9
|
+
} from "./components/SmartglassesSpatialView.js";
|
|
10
|
+
const EMPTY_REPORT = {
|
|
11
|
+
ok: false,
|
|
12
|
+
generatedAt: "",
|
|
13
|
+
transport: null,
|
|
14
|
+
connected: false,
|
|
15
|
+
lenses: { left: "idle", right: "idle" },
|
|
16
|
+
scanDiagnosis: "not_scanned",
|
|
17
|
+
physicalBlocker: "not_connected",
|
|
18
|
+
setupHint: "Connect both left and right lenses as one headset before running validation.",
|
|
19
|
+
nextAction: "Connect Headset",
|
|
20
|
+
serialNumber: null,
|
|
21
|
+
tests: {},
|
|
22
|
+
missingEvidence: [],
|
|
23
|
+
events: [],
|
|
24
|
+
writes: [],
|
|
25
|
+
audio: [],
|
|
26
|
+
wifi: { available: false, status: "Not checked", networks: [] },
|
|
27
|
+
headsetState: {
|
|
28
|
+
physical: null,
|
|
29
|
+
battery: null,
|
|
30
|
+
batteryLevels: {},
|
|
31
|
+
device: null
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const EMPTY_SMARTGLASSES = {
|
|
35
|
+
report: EMPTY_REPORT,
|
|
36
|
+
micEnabled: false,
|
|
37
|
+
wifiSsid: "",
|
|
38
|
+
wifiPassword: "",
|
|
39
|
+
testText: "Smartglasses display test.",
|
|
40
|
+
activePlatform: "desktop",
|
|
41
|
+
busy: null,
|
|
42
|
+
error: null
|
|
43
|
+
};
|
|
44
|
+
let currentFacewear = EMPTY_FACEWEAR_SNAPSHOT;
|
|
45
|
+
let currentSmartglasses = EMPTY_SMARTGLASSES;
|
|
46
|
+
function setFacewearTerminalSnapshot(next) {
|
|
47
|
+
currentFacewear = next;
|
|
48
|
+
}
|
|
49
|
+
function registerFacewearTerminalView() {
|
|
50
|
+
return registerSpatialTerminalView(
|
|
51
|
+
"facewear",
|
|
52
|
+
() => createElement(FacewearSpatialView, { snapshot: currentFacewear })
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
function setSmartglassesTerminalSnapshot(next) {
|
|
56
|
+
currentSmartglasses = next;
|
|
57
|
+
}
|
|
58
|
+
function registerSmartglassesTerminalView() {
|
|
59
|
+
return registerSpatialTerminalView(
|
|
60
|
+
"smartglasses",
|
|
61
|
+
() => createElement(SmartglassesSpatialView, { snapshot: currentSmartglasses })
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
registerFacewearTerminalView,
|
|
66
|
+
registerSmartglassesTerminalView,
|
|
67
|
+
setFacewearTerminalSnapshot,
|
|
68
|
+
setSmartglassesTerminalSnapshot
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=register-terminal-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/register-terminal-view.tsx"],"sourcesContent":["/**\n * Register the facewear + smartglasses views for terminal rendering.\n *\n * The agent terminal mounts plugin views by id from the `@elizaos/tui` terminal\n * registry. This makes each view's `tui` modality render for real in the\n * terminal (the unified {@link FacewearSpatialView} / {@link\n * SmartglassesSpatialView}) rather than only navigating a GUI shell. A\n * module-level snapshot per view lets a host push live data; with nothing paired\n * each defaults to a sensible empty/disconnected state.\n */\n\nimport { registerSpatialTerminalView } from \"@elizaos/ui/spatial/tui\";\nimport { createElement } from \"react\";\nimport {\n EMPTY_FACEWEAR_SNAPSHOT,\n type FacewearSnapshot,\n FacewearSpatialView,\n} from \"./components/FacewearSpatialView.js\";\nimport {\n type SmartglassesSnapshot,\n SmartglassesSpatialView,\n} from \"./components/SmartglassesSpatialView.js\";\nimport type { HardwareReport } from \"./ui/SmartglassesView.helpers.js\";\n\nconst EMPTY_REPORT: HardwareReport = {\n ok: false,\n generatedAt: \"\",\n transport: null,\n connected: false,\n lenses: { left: \"idle\", right: \"idle\" },\n scanDiagnosis: \"not_scanned\",\n physicalBlocker: \"not_connected\",\n setupHint:\n \"Connect both left and right lenses as one headset before running validation.\",\n nextAction: \"Connect Headset\",\n serialNumber: null,\n tests: {},\n missingEvidence: [],\n events: [],\n writes: [],\n audio: [],\n wifi: { available: false, status: \"Not checked\", networks: [] },\n headsetState: {\n physical: null,\n battery: null,\n batteryLevels: {},\n device: null,\n },\n};\n\nconst EMPTY_SMARTGLASSES: SmartglassesSnapshot = {\n report: EMPTY_REPORT,\n micEnabled: false,\n wifiSsid: \"\",\n wifiPassword: \"\",\n testText: \"Smartglasses display test.\",\n activePlatform: \"desktop\",\n busy: null,\n error: null,\n};\n\nlet currentFacewear: FacewearSnapshot = EMPTY_FACEWEAR_SNAPSHOT;\nlet currentSmartglasses: SmartglassesSnapshot = EMPTY_SMARTGLASSES;\n\n/** Update the snapshot the registered facewear terminal view renders from. */\nexport function setFacewearTerminalSnapshot(next: FacewearSnapshot): void {\n currentFacewear = next;\n}\n\n/** Register the facewear terminal view; returns an unregister function. */\nexport function registerFacewearTerminalView(): () => void {\n return registerSpatialTerminalView(\"facewear\", () =>\n createElement(FacewearSpatialView, { snapshot: currentFacewear }),\n );\n}\n\n/** Update the snapshot the registered smartglasses terminal view renders from. */\nexport function setSmartglassesTerminalSnapshot(\n next: SmartglassesSnapshot,\n): void {\n currentSmartglasses = next;\n}\n\n/** Register the smartglasses terminal view; returns an unregister function. */\nexport function registerSmartglassesTerminalView(): () => void {\n return registerSpatialTerminalView(\"smartglasses\", () =>\n createElement(SmartglassesSpatialView, { snapshot: currentSmartglasses }),\n );\n}\n"],"mappings":"AAWA,SAAS,mCAAmC;AAC5C,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EAEA;AAAA,OACK;AACP;AAAA,EAEE;AAAA,OACK;AAGP,MAAM,eAA+B;AAAA,EACnC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,WAAW;AAAA,EACX,WAAW;AAAA,EACX,QAAQ,EAAE,MAAM,QAAQ,OAAO,OAAO;AAAA,EACtC,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,WACE;AAAA,EACF,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,OAAO,CAAC;AAAA,EACR,iBAAiB,CAAC;AAAA,EAClB,QAAQ,CAAC;AAAA,EACT,QAAQ,CAAC;AAAA,EACT,OAAO,CAAC;AAAA,EACR,MAAM,EAAE,WAAW,OAAO,QAAQ,eAAe,UAAU,CAAC,EAAE;AAAA,EAC9D,cAAc;AAAA,IACZ,UAAU;AAAA,IACV,SAAS;AAAA,IACT,eAAe,CAAC;AAAA,IAChB,QAAQ;AAAA,EACV;AACF;AAEA,MAAM,qBAA2C;AAAA,EAC/C,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,cAAc;AAAA,EACd,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,OAAO;AACT;AAEA,IAAI,kBAAoC;AACxC,IAAI,sBAA4C;AAGzC,SAAS,4BAA4B,MAA8B;AACxE,oBAAkB;AACpB;AAGO,SAAS,+BAA2C;AACzD,SAAO;AAAA,IAA4B;AAAA,IAAY,MAC7C,cAAc,qBAAqB,EAAE,UAAU,gBAAgB,CAAC;AAAA,EAClE;AACF;AAGO,SAAS,gCACd,MACM;AACN,wBAAsB;AACxB;AAGO,SAAS,mCAA+C;AAC7D,SAAO;AAAA,IAA4B;AAAA,IAAgB,MACjD,cAAc,yBAAyB,EAAE,UAAU,oBAAoB,CAAC;AAAA,EAC1E;AACF;","names":[]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ComponentType } from "react";
|
|
2
|
+
type DeferredViewComponent = ComponentType<Record<string, unknown>>;
|
|
3
|
+
export declare const FacewearAppView: DeferredViewComponent;
|
|
4
|
+
export declare const FacewearTuiView: DeferredViewComponent;
|
|
5
|
+
export declare const SmartglassesView: DeferredViewComponent;
|
|
6
|
+
export declare const SmartglassesTuiView: DeferredViewComponent;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAsC,MAAM,OAAO,CAAC;AAE/E,KAAK,qBAAqB,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAuEpE,eAAO,MAAM,eAAe,uBAAyC,CAAC;AACtE,eAAO,MAAM,eAAe,uBAAyC,CAAC;AACtE,eAAO,MAAM,gBAAgB,uBAA0C,CAAC;AACxE,eAAO,MAAM,mBAAmB,uBAA6C,CAAC"}
|