@agentdeck/bridge 0.1.0 → 0.2.1
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/LICENSE +21 -0
- package/dist/adapters/claude-code.d.ts +11 -27
- package/dist/adapters/claude-code.d.ts.map +1 -1
- package/dist/adapters/claude-code.js +29 -123
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/adapters/codex-cli.d.ts +21 -0
- package/dist/adapters/codex-cli.d.ts.map +1 -0
- package/dist/adapters/codex-cli.js +53 -0
- package/dist/adapters/codex-cli.js.map +1 -0
- package/dist/adapters/index.d.ts +4 -0
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +13 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/monitor.d.ts +34 -0
- package/dist/adapters/monitor.d.ts.map +1 -0
- package/dist/adapters/monitor.js +86 -0
- package/dist/adapters/monitor.js.map +1 -0
- package/dist/adapters/openclaw.d.ts +36 -2
- package/dist/adapters/openclaw.d.ts.map +1 -1
- package/dist/adapters/openclaw.js +329 -59
- package/dist/adapters/openclaw.js.map +1 -1
- package/dist/adapters/opencode-adapter.d.ts +48 -0
- package/dist/adapters/opencode-adapter.d.ts.map +1 -0
- package/dist/adapters/opencode-adapter.js +345 -0
- package/dist/adapters/opencode-adapter.js.map +1 -0
- package/dist/adapters/pty-adapter.d.ts +56 -0
- package/dist/adapters/pty-adapter.d.ts.map +1 -0
- package/dist/adapters/pty-adapter.js +143 -0
- package/dist/adapters/pty-adapter.js.map +1 -0
- package/dist/adb-reverse.d.ts +25 -0
- package/dist/adb-reverse.d.ts.map +1 -0
- package/dist/adb-reverse.js +129 -0
- package/dist/adb-reverse.js.map +1 -0
- package/dist/antigravity-local.d.ts +7 -0
- package/dist/antigravity-local.d.ts.map +1 -0
- package/dist/antigravity-local.js +153 -0
- package/dist/antigravity-local.js.map +1 -0
- package/dist/apme/adapters/claude-hook.d.ts +15 -0
- package/dist/apme/adapters/claude-hook.d.ts.map +1 -0
- package/dist/apme/adapters/claude-hook.js +85 -0
- package/dist/apme/adapters/claude-hook.js.map +1 -0
- package/dist/apme/adapters/claude-pty.d.ts +28 -0
- package/dist/apme/adapters/claude-pty.d.ts.map +1 -0
- package/dist/apme/adapters/claude-pty.js +88 -0
- package/dist/apme/adapters/claude-pty.js.map +1 -0
- package/dist/apme/adapters/timeline.d.ts +16 -0
- package/dist/apme/adapters/timeline.d.ts.map +1 -0
- package/dist/apme/adapters/timeline.js +66 -0
- package/dist/apme/adapters/timeline.js.map +1 -0
- package/dist/apme/classifier.d.ts +53 -0
- package/dist/apme/classifier.d.ts.map +1 -0
- package/dist/apme/classifier.js +266 -0
- package/dist/apme/classifier.js.map +1 -0
- package/dist/apme/claude-transcript-reader.d.ts +38 -0
- package/dist/apme/claude-transcript-reader.d.ts.map +1 -0
- package/dist/apme/claude-transcript-reader.js +127 -0
- package/dist/apme/claude-transcript-reader.js.map +1 -0
- package/dist/apme/collector.d.ts +108 -0
- package/dist/apme/collector.d.ts.map +1 -0
- package/dist/apme/collector.js +659 -0
- package/dist/apme/collector.js.map +1 -0
- package/dist/apme/dashboard-html.d.ts +9 -0
- package/dist/apme/dashboard-html.d.ts.map +1 -0
- package/dist/apme/dashboard-html.js +416 -0
- package/dist/apme/dashboard-html.js.map +1 -0
- package/dist/apme/http.d.ts +19 -0
- package/dist/apme/http.d.ts.map +1 -0
- package/dist/apme/http.js +210 -0
- package/dist/apme/http.js.map +1 -0
- package/dist/apme/hw-sampler.d.ts +30 -0
- package/dist/apme/hw-sampler.d.ts.map +1 -0
- package/dist/apme/hw-sampler.js +106 -0
- package/dist/apme/hw-sampler.js.map +1 -0
- package/dist/apme/index.d.ts +43 -0
- package/dist/apme/index.d.ts.map +1 -0
- package/dist/apme/index.js +75 -0
- package/dist/apme/index.js.map +1 -0
- package/dist/apme/outcome.d.ts +48 -0
- package/dist/apme/outcome.d.ts.map +1 -0
- package/dist/apme/outcome.js +232 -0
- package/dist/apme/outcome.js.map +1 -0
- package/dist/apme/recommend.d.ts +32 -0
- package/dist/apme/recommend.d.ts.map +1 -0
- package/dist/apme/recommend.js +41 -0
- package/dist/apme/recommend.js.map +1 -0
- package/dist/apme/runner.d.ts +94 -0
- package/dist/apme/runner.d.ts.map +1 -0
- package/dist/apme/runner.js +812 -0
- package/dist/apme/runner.js.map +1 -0
- package/dist/apme/settings.d.ts +65 -0
- package/dist/apme/settings.d.ts.map +1 -0
- package/dist/apme/settings.js +97 -0
- package/dist/apme/settings.js.map +1 -0
- package/dist/apme/store.d.ts +99 -0
- package/dist/apme/store.d.ts.map +1 -0
- package/dist/apme/store.js +911 -0
- package/dist/apme/store.js.map +1 -0
- package/dist/apme/tuner.d.ts +64 -0
- package/dist/apme/tuner.d.ts.map +1 -0
- package/dist/apme/tuner.js +297 -0
- package/dist/apme/tuner.js.map +1 -0
- package/dist/apme/types.d.ts +11 -0
- package/dist/apme/types.d.ts.map +1 -0
- package/dist/apme/types.js +10 -0
- package/dist/apme/types.js.map +1 -0
- package/dist/auth.d.ts +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +15 -5
- package/dist/auth.js.map +1 -1
- package/dist/bridge-core.d.ts +162 -0
- package/dist/bridge-core.d.ts.map +1 -0
- package/dist/bridge-core.js +627 -0
- package/dist/bridge-core.js.map +1 -0
- package/dist/check-deps.d.ts +3 -1
- package/dist/check-deps.d.ts.map +1 -1
- package/dist/check-deps.js +34 -13
- package/dist/check-deps.js.map +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1235 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-auth.d.ts +10 -0
- package/dist/codex-auth.d.ts.map +1 -0
- package/dist/codex-auth.js +63 -0
- package/dist/codex-auth.js.map +1 -0
- package/dist/codex-output-parser.d.ts +21 -0
- package/dist/codex-output-parser.d.ts.map +1 -0
- package/dist/codex-output-parser.js +253 -0
- package/dist/codex-output-parser.js.map +1 -0
- package/dist/d200h/hid-protocol.d.ts +62 -0
- package/dist/d200h/hid-protocol.d.ts.map +1 -0
- package/dist/d200h/hid-protocol.js +124 -0
- package/dist/d200h/hid-protocol.js.map +1 -0
- package/dist/d200h/image-renderer.d.ts +36 -0
- package/dist/d200h/image-renderer.d.ts.map +1 -0
- package/dist/d200h/image-renderer.js +487 -0
- package/dist/d200h/image-renderer.js.map +1 -0
- package/dist/daemon-server.d.ts +19 -0
- package/dist/daemon-server.d.ts.map +1 -0
- package/dist/daemon-server.js +1168 -0
- package/dist/daemon-server.js.map +1 -0
- package/dist/daemon-ws-client.d.ts +82 -0
- package/dist/daemon-ws-client.d.ts.map +1 -0
- package/dist/daemon-ws-client.js +179 -0
- package/dist/daemon-ws-client.js.map +1 -0
- package/dist/daemon.d.ts +10 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +56 -0
- package/dist/daemon.js.map +1 -0
- package/dist/display-monitor.d.ts +25 -0
- package/dist/display-monitor.d.ts.map +1 -0
- package/dist/display-monitor.js +143 -0
- package/dist/display-monitor.js.map +1 -0
- package/dist/esp32-serial.d.ts +112 -0
- package/dist/esp32-serial.d.ts.map +1 -0
- package/dist/esp32-serial.js +502 -0
- package/dist/esp32-serial.js.map +1 -0
- package/dist/gateway-probe.d.ts +12 -0
- package/dist/gateway-probe.d.ts.map +1 -0
- package/dist/gateway-probe.js +39 -0
- package/dist/gateway-probe.js.map +1 -0
- package/dist/hook-migration.d.ts +2 -0
- package/dist/hook-migration.d.ts.map +1 -0
- package/dist/hook-migration.js +104 -0
- package/dist/hook-migration.js.map +1 -0
- package/dist/hook-server.d.ts +29 -0
- package/dist/hook-server.d.ts.map +1 -1
- package/dist/hook-server.js +366 -8
- package/dist/hook-server.js.map +1 -1
- package/dist/index.d.ts +20 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1304 -562
- package/dist/index.js.map +1 -1
- package/dist/log-stream.d.ts +26 -0
- package/dist/log-stream.d.ts.map +1 -0
- package/dist/log-stream.js +111 -0
- package/dist/log-stream.js.map +1 -0
- package/dist/logger.d.ts +9 -2
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +36 -5
- package/dist/logger.js.map +1 -1
- package/dist/mdns.d.ts +15 -1
- package/dist/mdns.d.ts.map +1 -1
- package/dist/mdns.js +143 -28
- package/dist/mdns.js.map +1 -1
- package/dist/mlx-probe.d.ts +14 -0
- package/dist/mlx-probe.d.ts.map +1 -0
- package/dist/mlx-probe.js +44 -0
- package/dist/mlx-probe.js.map +1 -0
- package/dist/model-catalog.d.ts +5 -3
- package/dist/model-catalog.d.ts.map +1 -1
- package/dist/model-catalog.js +45 -29
- package/dist/model-catalog.js.map +1 -1
- package/dist/modules/adb-module.d.ts +14 -0
- package/dist/modules/adb-module.d.ts.map +1 -0
- package/dist/modules/adb-module.js +36 -0
- package/dist/modules/adb-module.js.map +1 -0
- package/dist/modules/d200h-module.d.ts +43 -0
- package/dist/modules/d200h-module.d.ts.map +1 -0
- package/dist/modules/d200h-module.js +360 -0
- package/dist/modules/d200h-module.js.map +1 -0
- package/dist/modules/d200h-renderer.d.ts +7 -0
- package/dist/modules/d200h-renderer.d.ts.map +1 -0
- package/dist/modules/d200h-renderer.js +321 -0
- package/dist/modules/d200h-renderer.js.map +1 -0
- package/dist/modules/index.d.ts +23 -0
- package/dist/modules/index.d.ts.map +1 -0
- package/dist/modules/index.js +65 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/modules/mdns-module.d.ts +12 -0
- package/dist/modules/mdns-module.d.ts.map +1 -0
- package/dist/modules/mdns-module.js +21 -0
- package/dist/modules/mdns-module.js.map +1 -0
- package/dist/modules/pixoo-module.d.ts +8 -0
- package/dist/modules/pixoo-module.d.ts.map +1 -0
- package/dist/modules/pixoo-module.js +24 -0
- package/dist/modules/pixoo-module.js.map +1 -0
- package/dist/modules/serial-module.d.ts +18 -0
- package/dist/modules/serial-module.d.ts.map +1 -0
- package/dist/modules/serial-module.js +47 -0
- package/dist/modules/serial-module.js.map +1 -0
- package/dist/modules/types.d.ts +39 -0
- package/dist/modules/types.d.ts.map +1 -0
- package/dist/modules/types.js +2 -0
- package/dist/modules/types.js.map +1 -0
- package/dist/ollama-probe.d.ts +13 -0
- package/dist/ollama-probe.d.ts.map +1 -0
- package/dist/ollama-probe.js +46 -0
- package/dist/ollama-probe.js.map +1 -0
- package/dist/opencode-client.d.ts +126 -0
- package/dist/opencode-client.d.ts.map +1 -0
- package/dist/opencode-client.js +181 -0
- package/dist/opencode-client.js.map +1 -0
- package/dist/output-parser.d.ts +3 -0
- package/dist/output-parser.d.ts.map +1 -1
- package/dist/output-parser.js +29 -3
- package/dist/output-parser.js.map +1 -1
- package/dist/passive-observer.d.ts +38 -0
- package/dist/passive-observer.d.ts.map +1 -0
- package/dist/passive-observer.js +632 -0
- package/dist/passive-observer.js.map +1 -0
- package/dist/pixoo/pixoo-bridge.d.ts +50 -0
- package/dist/pixoo/pixoo-bridge.d.ts.map +1 -0
- package/dist/pixoo/pixoo-bridge.js +280 -0
- package/dist/pixoo/pixoo-bridge.js.map +1 -0
- package/dist/pixoo/pixoo-camera.d.ts +80 -0
- package/dist/pixoo/pixoo-camera.d.ts.map +1 -0
- package/dist/pixoo/pixoo-camera.js +271 -0
- package/dist/pixoo/pixoo-camera.js.map +1 -0
- package/dist/pixoo/pixoo-client.d.ts +67 -0
- package/dist/pixoo/pixoo-client.d.ts.map +1 -0
- package/dist/pixoo/pixoo-client.js +335 -0
- package/dist/pixoo/pixoo-client.js.map +1 -0
- package/dist/pixoo/pixoo-font.d.ts +24 -0
- package/dist/pixoo/pixoo-font.d.ts.map +1 -0
- package/dist/pixoo/pixoo-font.js +121 -0
- package/dist/pixoo/pixoo-font.js.map +1 -0
- package/dist/pixoo/pixoo-renderer.d.ts +32 -0
- package/dist/pixoo/pixoo-renderer.d.ts.map +1 -0
- package/dist/pixoo/pixoo-renderer.js +696 -0
- package/dist/pixoo/pixoo-renderer.js.map +1 -0
- package/dist/pixoo/pixoo-settings.d.ts +10 -0
- package/dist/pixoo/pixoo-settings.d.ts.map +1 -0
- package/dist/pixoo/pixoo-settings.js +47 -0
- package/dist/pixoo/pixoo-settings.js.map +1 -0
- package/dist/pixoo/pixoo-sprites.d.ts +187 -0
- package/dist/pixoo/pixoo-sprites.d.ts.map +1 -0
- package/dist/pixoo/pixoo-sprites.js +926 -0
- package/dist/pixoo/pixoo-sprites.js.map +1 -0
- package/dist/pty-manager.d.ts +1 -1
- package/dist/pty-manager.d.ts.map +1 -1
- package/dist/pty-manager.js +36 -15
- package/dist/pty-manager.js.map +1 -1
- package/dist/session-aggregator.d.ts +41 -0
- package/dist/session-aggregator.d.ts.map +1 -0
- package/dist/session-aggregator.js +76 -0
- package/dist/session-aggregator.js.map +1 -0
- package/dist/session-focus-relay.d.ts +35 -0
- package/dist/session-focus-relay.d.ts.map +1 -0
- package/dist/session-focus-relay.js +127 -0
- package/dist/session-focus-relay.js.map +1 -0
- package/dist/session-registry.d.ts +88 -1
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/session-registry.js +222 -15
- package/dist/session-registry.js.map +1 -1
- package/dist/session-timeline-relay.d.ts +27 -0
- package/dist/session-timeline-relay.d.ts.map +1 -0
- package/dist/session-timeline-relay.js +124 -0
- package/dist/session-timeline-relay.js.map +1 -0
- package/dist/state-machine.d.ts +1 -0
- package/dist/state-machine.d.ts.map +1 -1
- package/dist/state-machine.js +14 -0
- package/dist/state-machine.js.map +1 -1
- package/dist/terminal-status.d.ts +28 -0
- package/dist/terminal-status.d.ts.map +1 -0
- package/dist/terminal-status.js +152 -0
- package/dist/terminal-status.js.map +1 -0
- package/dist/timeline-store.d.ts +22 -0
- package/dist/timeline-store.d.ts.map +1 -0
- package/dist/timeline-store.js +79 -0
- package/dist/timeline-store.js.map +1 -0
- package/dist/timeline-summarizer.d.ts +14 -0
- package/dist/timeline-summarizer.d.ts.map +1 -0
- package/dist/timeline-summarizer.js +154 -0
- package/dist/timeline-summarizer.js.map +1 -0
- package/dist/tts.d.ts +25 -0
- package/dist/tts.d.ts.map +1 -0
- package/dist/tts.js +99 -0
- package/dist/tts.js.map +1 -0
- package/dist/tui/ansi.d.ts +92 -0
- package/dist/tui/ansi.d.ts.map +1 -0
- package/dist/tui/ansi.js +181 -0
- package/dist/tui/ansi.js.map +1 -0
- package/dist/tui/dashboard.d.ts +35 -0
- package/dist/tui/dashboard.d.ts.map +1 -0
- package/dist/tui/dashboard.js +436 -0
- package/dist/tui/dashboard.js.map +1 -0
- package/dist/tui/gauge.d.ts +15 -0
- package/dist/tui/gauge.d.ts.map +1 -0
- package/dist/tui/gauge.js +82 -0
- package/dist/tui/gauge.js.map +1 -0
- package/dist/tui/renderer.d.ts +15 -0
- package/dist/tui/renderer.d.ts.map +1 -0
- package/dist/tui/renderer.js +758 -0
- package/dist/tui/renderer.js.map +1 -0
- package/dist/tui/screen.d.ts +27 -0
- package/dist/tui/screen.d.ts.map +1 -0
- package/dist/tui/screen.js +109 -0
- package/dist/tui/screen.js.map +1 -0
- package/dist/tui/terrarium.d.ts +96 -0
- package/dist/tui/terrarium.d.ts.map +1 -0
- package/dist/tui/terrarium.js +912 -0
- package/dist/tui/terrarium.js.map +1 -0
- package/dist/types.d.ts +4 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -2
- package/dist/types.js.map +1 -1
- package/dist/usage-api.d.ts +9 -2
- package/dist/usage-api.d.ts.map +1 -1
- package/dist/usage-api.js +224 -42
- package/dist/usage-api.js.map +1 -1
- package/dist/usage-event.d.ts +12 -0
- package/dist/usage-event.d.ts.map +1 -0
- package/dist/usage-event.js +78 -0
- package/dist/usage-event.js.map +1 -0
- package/dist/usage-tracker.d.ts +4 -0
- package/dist/usage-tracker.d.ts.map +1 -1
- package/dist/usage-tracker.js +17 -0
- package/dist/usage-tracker.js.map +1 -1
- package/dist/utility-proxy.d.ts +30 -0
- package/dist/utility-proxy.d.ts.map +1 -0
- package/dist/utility-proxy.js +217 -0
- package/dist/utility-proxy.js.map +1 -0
- package/dist/utils/project-name.d.ts +22 -0
- package/dist/utils/project-name.d.ts.map +1 -0
- package/dist/utils/project-name.js +72 -0
- package/dist/utils/project-name.js.map +1 -0
- package/dist/version-check.d.ts +26 -0
- package/dist/version-check.d.ts.map +1 -0
- package/dist/version-check.js +225 -0
- package/dist/version-check.js.map +1 -0
- package/dist/voice-assistant.d.ts +63 -0
- package/dist/voice-assistant.d.ts.map +1 -0
- package/dist/voice-assistant.js +406 -0
- package/dist/voice-assistant.js.map +1 -0
- package/dist/voice.d.ts +2 -0
- package/dist/voice.d.ts.map +1 -1
- package/dist/voice.js +26 -1
- package/dist/voice.js.map +1 -1
- package/dist/wake-word.d.ts +35 -0
- package/dist/wake-word.d.ts.map +1 -0
- package/dist/wake-word.js +225 -0
- package/dist/wake-word.js.map +1 -0
- package/dist/whisper-server-manager.d.ts +1 -1
- package/dist/whisper-server-manager.js +1 -1
- package/dist/wifi-config.d.ts +24 -0
- package/dist/wifi-config.d.ts.map +1 -0
- package/dist/wifi-config.js +84 -0
- package/dist/wifi-config.js.map +1 -0
- package/dist/ws-server.d.ts +12 -0
- package/dist/ws-server.d.ts.map +1 -1
- package/dist/ws-server.js +81 -3
- package/dist/ws-server.js.map +1 -1
- package/package.json +21 -13
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESP32 Serial Bridge — bidirectional USB serial communication.
|
|
3
|
+
*
|
|
4
|
+
* Detects ESP32 devices (CH340/CP210x) on USB serial ports,
|
|
5
|
+
* opens the port for read+write, and sends newline-delimited JSON
|
|
6
|
+
* matching the same protocol as WebSocket.
|
|
7
|
+
*
|
|
8
|
+
* Read path: parses newline-delimited JSON from ESP32 (device_info,
|
|
9
|
+
* wifi_provision_ack, wifi_status). Non-JSON debug lines are ignored.
|
|
10
|
+
*
|
|
11
|
+
* ESP32 side reads lines starting with '{' and passes to Protocol::parseMessage().
|
|
12
|
+
*/
|
|
13
|
+
import { type WriteStream, type ReadStream } from 'fs';
|
|
14
|
+
import type { BridgeEvent } from './types.js';
|
|
15
|
+
import type { ESP32ToHostMessage, WifiProvisionMessage } from '@agentdeck/shared/protocol';
|
|
16
|
+
/** @internal Exported for testing only */
|
|
17
|
+
export declare const ESP32_PORT_PATTERNS: RegExp[];
|
|
18
|
+
/** @internal Exported for testing only */
|
|
19
|
+
export declare const EXCLUDE_PATTERNS: RegExp[];
|
|
20
|
+
/** @internal Exported for testing only */
|
|
21
|
+
export interface SerialConnection {
|
|
22
|
+
port: string;
|
|
23
|
+
stream: WriteStream;
|
|
24
|
+
reader: ReadStream | null;
|
|
25
|
+
readBuf: string;
|
|
26
|
+
connected: boolean;
|
|
27
|
+
deviceInfo: {
|
|
28
|
+
board?: string;
|
|
29
|
+
version?: string;
|
|
30
|
+
wifiConfigured?: boolean;
|
|
31
|
+
wifiConnected?: boolean;
|
|
32
|
+
} | null;
|
|
33
|
+
provisionSent: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Prepare a BridgeEvent for serial transmission.
|
|
37
|
+
* - Pre-format ISO reset times (ESP32 has no NTP)
|
|
38
|
+
* - Strip fields the ESP32 firmware doesn't parse (reduce size for small RX buffers)
|
|
39
|
+
*/
|
|
40
|
+
/** @internal Exported for testing only */
|
|
41
|
+
export declare function prepareForSerial(event: BridgeEvent): BridgeEvent;
|
|
42
|
+
/** @internal Exported for testing only */
|
|
43
|
+
export declare function handleSerialLine(conn: SerialConnection, line: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Register a callback that returns the current state_update event.
|
|
46
|
+
* Used to send periodic heartbeats so ESP32 gets data even without
|
|
47
|
+
* state changes (e.g., after reboot while bridge is idle).
|
|
48
|
+
*/
|
|
49
|
+
export declare function setESP32StateProvider(provider: () => BridgeEvent | null): void;
|
|
50
|
+
/**
|
|
51
|
+
* Register a callback that returns the current usage_update event.
|
|
52
|
+
* Heartbeat sends both state + usage every cycle so ESP32 stays in sync.
|
|
53
|
+
*/
|
|
54
|
+
export declare function setESP32UsageProvider(provider: () => BridgeEvent | null): void;
|
|
55
|
+
/**
|
|
56
|
+
* Register a provider that returns all initial state events (state + usage + sessions).
|
|
57
|
+
* Called when a new ESP32 device connects to send full state immediately.
|
|
58
|
+
*/
|
|
59
|
+
export declare function setESP32InitialStateProvider(provider: () => BridgeEvent[]): void;
|
|
60
|
+
/**
|
|
61
|
+
* Register a handler for messages received from ESP32 devices.
|
|
62
|
+
* Called with (portPath, parsedMessage) for each JSON message.
|
|
63
|
+
*/
|
|
64
|
+
export declare function onESP32Message(handler: (port: string, msg: ESP32ToHostMessage) => void): void;
|
|
65
|
+
/**
|
|
66
|
+
* Start ESP32 serial bridge.
|
|
67
|
+
* Detects USB serial ports and opens connections.
|
|
68
|
+
* Call broadcast() to send events to all connected ESP32 devices.
|
|
69
|
+
*
|
|
70
|
+
* Non-blocking: initial device detection runs in background so a hung
|
|
71
|
+
* USB port (stty stuck in kernel I/O) cannot block bridge startup.
|
|
72
|
+
*/
|
|
73
|
+
export declare function startESP32Serial(): void;
|
|
74
|
+
/**
|
|
75
|
+
* Broadcast a BridgeEvent to all connected ESP32 devices via serial.
|
|
76
|
+
*/
|
|
77
|
+
export declare function broadcastESP32(event: BridgeEvent): void;
|
|
78
|
+
/**
|
|
79
|
+
* Send a WiFi provision message to a specific ESP32 device by port path.
|
|
80
|
+
*/
|
|
81
|
+
export declare function sendWifiProvision(port: string, msg: WifiProvisionMessage): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Send WiFi provision to all connected ESP32 devices that haven't been provisioned.
|
|
84
|
+
*/
|
|
85
|
+
export declare function sendWifiProvisionToAll(msg: WifiProvisionMessage): number;
|
|
86
|
+
/**
|
|
87
|
+
* Get device info for all connected ESP32 devices.
|
|
88
|
+
*/
|
|
89
|
+
export declare function getESP32DeviceInfo(): Array<{
|
|
90
|
+
port: string;
|
|
91
|
+
board?: string;
|
|
92
|
+
version?: string;
|
|
93
|
+
wifiConfigured?: boolean;
|
|
94
|
+
wifiConnected?: boolean;
|
|
95
|
+
}>;
|
|
96
|
+
/**
|
|
97
|
+
* Wake recovery — close stale file descriptors, force immediate re-poll.
|
|
98
|
+
*/
|
|
99
|
+
export declare function handleESP32Wake(): void;
|
|
100
|
+
/**
|
|
101
|
+
* Stop ESP32 serial bridge and close all connections.
|
|
102
|
+
*/
|
|
103
|
+
export declare function stopESP32Serial(): void;
|
|
104
|
+
/**
|
|
105
|
+
* Get number of connected ESP32 devices.
|
|
106
|
+
*/
|
|
107
|
+
export declare function esp32ConnectionCount(): number;
|
|
108
|
+
/**
|
|
109
|
+
* Get list of connected ESP32 serial port paths.
|
|
110
|
+
*/
|
|
111
|
+
export declare function getESP32Ports(): string[];
|
|
112
|
+
//# sourceMappingURL=esp32-serial.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"esp32-serial.d.ts","sourceRoot":"","sources":["../src/esp32-serial.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAuC,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,IAAI,CAAC;AAC5F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAI3F,0CAA0C;AAC1C,eAAO,MAAM,mBAAmB,UAM/B,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,gBAAgB,UAG5B,CAAC;AAEF,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3G,aAAa,EAAE,OAAO,CAAC;CACxB;AAgBD;;;;GAIG;AACH,0CAA0C;AAC1C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAuBhE;AA8CD,0CAA0C;AAC1C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAyB3E;AA4HD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,CAE9E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,CAE9E;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,WAAW,EAAE,GAAG,IAAI,CAEhF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,kBAAkB,KAAK,IAAI,GAAG,IAAI,CAE7F;AAgCD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAiBvC;AA0BD;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAsBvD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAOlF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,oBAAoB,GAAG,MAAM,CAaxE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAOjJ;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CActC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAiBtC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC"}
|
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESP32 Serial Bridge — bidirectional USB serial communication.
|
|
3
|
+
*
|
|
4
|
+
* Detects ESP32 devices (CH340/CP210x) on USB serial ports,
|
|
5
|
+
* opens the port for read+write, and sends newline-delimited JSON
|
|
6
|
+
* matching the same protocol as WebSocket.
|
|
7
|
+
*
|
|
8
|
+
* Read path: parses newline-delimited JSON from ESP32 (device_info,
|
|
9
|
+
* wifi_provision_ack, wifi_status). Non-JSON debug lines are ignored.
|
|
10
|
+
*
|
|
11
|
+
* ESP32 side reads lines starting with '{' and passes to Protocol::parseMessage().
|
|
12
|
+
*/
|
|
13
|
+
import { exec } from 'child_process';
|
|
14
|
+
import { createWriteStream, createReadStream } from 'fs';
|
|
15
|
+
import { SERIAL_FORWARDED_EVENTS } from '@agentdeck/shared/protocol';
|
|
16
|
+
import { formatResetTime } from '@agentdeck/shared';
|
|
17
|
+
import { debug } from './logger.js';
|
|
18
|
+
/** @internal Exported for testing only */
|
|
19
|
+
export const ESP32_PORT_PATTERNS = [
|
|
20
|
+
/\/dev\/cu\.usbserial-\d+/, // CP210x / CH340 (cu.usbserial-XXXX)
|
|
21
|
+
/\/dev\/cu\.wchusbserial\d+/, // CH340 (cu.wchusbserialXXXX — 86 Box)
|
|
22
|
+
/\/dev\/cu\.usbmodem\d+/, // Native USB JTAG (IPS 3.5", Round AMOLED)
|
|
23
|
+
/\/dev\/ttyUSB\d+/, // Linux CH340
|
|
24
|
+
/\/dev\/ttyACM\d+/, // Linux native USB
|
|
25
|
+
];
|
|
26
|
+
/** @internal Exported for testing only */
|
|
27
|
+
export const EXCLUDE_PATTERNS = [
|
|
28
|
+
/Bluetooth/i,
|
|
29
|
+
/WLAN/i,
|
|
30
|
+
];
|
|
31
|
+
let connections = [];
|
|
32
|
+
let pollTimer = null;
|
|
33
|
+
let heartbeatTimer = null;
|
|
34
|
+
let stateProvider = null;
|
|
35
|
+
let usageProvider = null;
|
|
36
|
+
let initialStateProvider = null;
|
|
37
|
+
let messageHandler = null;
|
|
38
|
+
// Events to forward — shared constant from @agentdeck/shared
|
|
39
|
+
const FORWARDED_EVENTS = SERIAL_FORWARDED_EVENTS;
|
|
40
|
+
// ESP32 without WiFi/NTP can't parse ISO dates — shared formatResetTime
|
|
41
|
+
// handles undefined and pre-formatted strings.
|
|
42
|
+
/**
|
|
43
|
+
* Prepare a BridgeEvent for serial transmission.
|
|
44
|
+
* - Pre-format ISO reset times (ESP32 has no NTP)
|
|
45
|
+
* - Strip fields the ESP32 firmware doesn't parse (reduce size for small RX buffers)
|
|
46
|
+
*/
|
|
47
|
+
/** @internal Exported for testing only */
|
|
48
|
+
export function prepareForSerial(event) {
|
|
49
|
+
const e = event;
|
|
50
|
+
if (event.type === 'usage_update') {
|
|
51
|
+
// Pre-format ISO dates + strip unused fields
|
|
52
|
+
const { ollamaStatus, tokenStatus, extraUsageEnabled, extraUsageMonthlyLimit, extraUsageUsedCredits, extraUsageUtilization, costSpent, costLimit, sessionPercent, resetTime, resetDate, ...keep } = e;
|
|
53
|
+
return {
|
|
54
|
+
...keep,
|
|
55
|
+
fiveHourResetsAt: formatResetTime(keep.fiveHourResetsAt),
|
|
56
|
+
sevenDayResetsAt: formatResetTime(keep.sevenDayResetsAt),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (event.type === 'state_update') {
|
|
60
|
+
// Strip agentCapabilities + other fields ESP32 doesn't parse
|
|
61
|
+
const { agentCapabilities, billingType, remoteUrl, diff, context, selectedOptionIndex, ...keep } = e;
|
|
62
|
+
return keep;
|
|
63
|
+
}
|
|
64
|
+
return event;
|
|
65
|
+
}
|
|
66
|
+
/** Run a shell command with timeout, escalating to SIGKILL if SIGTERM fails. */
|
|
67
|
+
function execWithKill(cmd, timeoutMs = 3000) {
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
const child = exec(cmd, { encoding: 'utf-8', timeout: timeoutMs }, (err, stdout) => {
|
|
70
|
+
if (err) {
|
|
71
|
+
reject(err);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
resolve(stdout);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// When exec timeout fires, it sends SIGTERM. But stty stuck in kernel I/O
|
|
78
|
+
// ignores SIGTERM. Schedule a SIGKILL as escalation.
|
|
79
|
+
const killTimer = setTimeout(() => {
|
|
80
|
+
try {
|
|
81
|
+
child.kill('SIGKILL');
|
|
82
|
+
}
|
|
83
|
+
catch { /* already dead */ }
|
|
84
|
+
}, timeoutMs + 1000);
|
|
85
|
+
child.on('exit', () => clearTimeout(killTimer));
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async function detectESP32Ports() {
|
|
89
|
+
try {
|
|
90
|
+
const platform = process.platform;
|
|
91
|
+
let output;
|
|
92
|
+
if (platform === 'darwin') {
|
|
93
|
+
output = await execWithKill('ls /dev/cu.usb* /dev/cu.wchusbserial* 2>/dev/null || true');
|
|
94
|
+
}
|
|
95
|
+
else if (platform === 'linux') {
|
|
96
|
+
output = await execWithKill('ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null || true');
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
const ports = output.trim().split('\n').filter(Boolean);
|
|
102
|
+
// Filter to ESP32 patterns, exclude known non-ESP32
|
|
103
|
+
return ports.filter(port => {
|
|
104
|
+
if (EXCLUDE_PATTERNS.some(p => p.test(port)))
|
|
105
|
+
return false;
|
|
106
|
+
return ESP32_PORT_PATTERNS.some(p => p.test(port));
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/** @internal Exported for testing only */
|
|
114
|
+
export function handleSerialLine(conn, line) {
|
|
115
|
+
if (!line.startsWith('{'))
|
|
116
|
+
return; // Skip debug output like "[WiFi] Connected"
|
|
117
|
+
try {
|
|
118
|
+
const msg = JSON.parse(line);
|
|
119
|
+
if (msg.type) {
|
|
120
|
+
debug('ESP32', `← ${conn.port}: ${msg.type}`);
|
|
121
|
+
conn.deviceInfo = conn.deviceInfo || {};
|
|
122
|
+
if (msg.type === 'device_info') {
|
|
123
|
+
conn.deviceInfo = {
|
|
124
|
+
board: msg.board,
|
|
125
|
+
version: msg.version,
|
|
126
|
+
wifiConfigured: msg.wifiConfigured,
|
|
127
|
+
wifiConnected: msg.wifiConnected,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (messageHandler) {
|
|
131
|
+
messageHandler(conn.port, msg);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// Not valid JSON — ignore (ESP32 debug output)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async function openPort(port) {
|
|
140
|
+
try {
|
|
141
|
+
// Open streams first, THEN configure baud rate.
|
|
142
|
+
// On macOS, opening a serial device can reset stty settings to defaults (9600).
|
|
143
|
+
// So stty must run AFTER the file descriptors are open.
|
|
144
|
+
const stream = createWriteStream(port, { flags: 'w' });
|
|
145
|
+
const conn = {
|
|
146
|
+
port, stream, reader: null, readBuf: '',
|
|
147
|
+
connected: true, deviceInfo: null, provisionSent: false,
|
|
148
|
+
};
|
|
149
|
+
stream.on('error', (err) => {
|
|
150
|
+
debug('ESP32', `Serial write error on ${port}: ${err.message}`);
|
|
151
|
+
conn.connected = false;
|
|
152
|
+
try {
|
|
153
|
+
conn.reader?.destroy();
|
|
154
|
+
}
|
|
155
|
+
catch { /* ignore */ }
|
|
156
|
+
});
|
|
157
|
+
stream.on('close', () => {
|
|
158
|
+
debug('ESP32', `Serial write closed: ${port}`);
|
|
159
|
+
conn.connected = false;
|
|
160
|
+
});
|
|
161
|
+
// Open read stream for incoming ESP32 messages
|
|
162
|
+
try {
|
|
163
|
+
const reader = createReadStream(port, { flags: 'r', encoding: 'utf-8' });
|
|
164
|
+
reader.pause(); // Don't process data until baud rate is configured
|
|
165
|
+
conn.reader = reader;
|
|
166
|
+
reader.on('data', (chunk) => {
|
|
167
|
+
const str = typeof chunk === 'string' ? chunk : chunk.toString('utf-8');
|
|
168
|
+
conn.readBuf += str;
|
|
169
|
+
let newlineIdx;
|
|
170
|
+
while ((newlineIdx = conn.readBuf.indexOf('\n')) !== -1) {
|
|
171
|
+
const line = conn.readBuf.slice(0, newlineIdx).trim();
|
|
172
|
+
conn.readBuf = conn.readBuf.slice(newlineIdx + 1);
|
|
173
|
+
if (line.length > 0) {
|
|
174
|
+
handleSerialLine(conn, line);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Prevent buffer bloat from non-newline data
|
|
178
|
+
if (conn.readBuf.length > 8192) {
|
|
179
|
+
conn.readBuf = '';
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
reader.on('error', (err) => {
|
|
183
|
+
debug('ESP32', `Serial read error on ${port}: ${err.message}`);
|
|
184
|
+
conn.connected = false;
|
|
185
|
+
try {
|
|
186
|
+
reader.destroy();
|
|
187
|
+
}
|
|
188
|
+
catch { /* ignore */ }
|
|
189
|
+
try {
|
|
190
|
+
conn.stream.end();
|
|
191
|
+
}
|
|
192
|
+
catch { /* ignore */ }
|
|
193
|
+
});
|
|
194
|
+
reader.on('close', () => {
|
|
195
|
+
conn.reader = null;
|
|
196
|
+
conn.connected = false;
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
debug('ESP32', `Failed to open reader on ${port}: ${err.message}`);
|
|
201
|
+
// Write-only still works for broadcast
|
|
202
|
+
}
|
|
203
|
+
// Configure baud rate AFTER file descriptors are open.
|
|
204
|
+
// On macOS, open() on serial devices can reset stty to defaults (9600).
|
|
205
|
+
// Skip stty for native USB CDC ports (cu.usbmodem / ttyACM) — they use
|
|
206
|
+
// USB bus speed, not UART baud rate. stty can interfere with open fds.
|
|
207
|
+
const isCDC = /usbmodem|ttyACM/.test(port);
|
|
208
|
+
if (!isCDC) {
|
|
209
|
+
const platform = process.platform;
|
|
210
|
+
if (platform === 'darwin') {
|
|
211
|
+
await execWithKill(`stty -f ${port} 115200 cs8 -cstopb -parenb -hupcl`);
|
|
212
|
+
}
|
|
213
|
+
else if (platform === 'linux') {
|
|
214
|
+
await execWithKill(`stty -F ${port} 115200 cs8 -cstopb -parenb -hupcl`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// Resume reader now that baud rate is configured (flush any garbled data from open→stty window)
|
|
218
|
+
if (conn.reader) {
|
|
219
|
+
conn.readBuf = '';
|
|
220
|
+
conn.reader.resume();
|
|
221
|
+
}
|
|
222
|
+
const portType = isCDC ? 'CDC' : 'UART';
|
|
223
|
+
debug('ESP32', `Opened serial port (r/w): ${port} [${portType}]`);
|
|
224
|
+
// Request device info on connect
|
|
225
|
+
sendToConnection(conn, JSON.stringify({ type: 'device_info_request' }));
|
|
226
|
+
// Send full initial state (state + usage + sessions) so ESP32 doesn't
|
|
227
|
+
// have to wait for next state change or heartbeat cycle
|
|
228
|
+
if (initialStateProvider) {
|
|
229
|
+
const events = initialStateProvider();
|
|
230
|
+
for (const event of events) {
|
|
231
|
+
if (!FORWARDED_EVENTS.has(event.type))
|
|
232
|
+
continue;
|
|
233
|
+
// Skip usage_update without API data — would reset ESP32 to "no data"
|
|
234
|
+
if (event.type === 'usage_update' && event.fiveHourPercent == null)
|
|
235
|
+
continue;
|
|
236
|
+
sendToConnection(conn, JSON.stringify(prepareForSerial(event)));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else if (stateProvider) {
|
|
240
|
+
const event = stateProvider();
|
|
241
|
+
if (event)
|
|
242
|
+
sendToConnection(conn, JSON.stringify(event));
|
|
243
|
+
}
|
|
244
|
+
return conn;
|
|
245
|
+
}
|
|
246
|
+
catch (err) {
|
|
247
|
+
debug('ESP32', `Failed to open ${port}: ${err.message}`);
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function sendToConnection(conn, json) {
|
|
252
|
+
if (!conn.connected)
|
|
253
|
+
return;
|
|
254
|
+
if (conn.stream.destroyed || !conn.stream.writable) {
|
|
255
|
+
conn.connected = false;
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
conn.stream.write(json + '\n');
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
conn.connected = false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Register a callback that returns the current state_update event.
|
|
267
|
+
* Used to send periodic heartbeats so ESP32 gets data even without
|
|
268
|
+
* state changes (e.g., after reboot while bridge is idle).
|
|
269
|
+
*/
|
|
270
|
+
export function setESP32StateProvider(provider) {
|
|
271
|
+
stateProvider = provider;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Register a callback that returns the current usage_update event.
|
|
275
|
+
* Heartbeat sends both state + usage every cycle so ESP32 stays in sync.
|
|
276
|
+
*/
|
|
277
|
+
export function setESP32UsageProvider(provider) {
|
|
278
|
+
usageProvider = provider;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Register a provider that returns all initial state events (state + usage + sessions).
|
|
282
|
+
* Called when a new ESP32 device connects to send full state immediately.
|
|
283
|
+
*/
|
|
284
|
+
export function setESP32InitialStateProvider(provider) {
|
|
285
|
+
initialStateProvider = provider;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Register a handler for messages received from ESP32 devices.
|
|
289
|
+
* Called with (portPath, parsedMessage) for each JSON message.
|
|
290
|
+
*/
|
|
291
|
+
export function onESP32Message(handler) {
|
|
292
|
+
messageHandler = handler;
|
|
293
|
+
}
|
|
294
|
+
let heartbeatCount = 0;
|
|
295
|
+
function sendHeartbeat() {
|
|
296
|
+
if (connections.length === 0)
|
|
297
|
+
return;
|
|
298
|
+
heartbeatCount++;
|
|
299
|
+
// Send state_update (stripped for serial — smaller payload)
|
|
300
|
+
if (stateProvider) {
|
|
301
|
+
const event = stateProvider();
|
|
302
|
+
if (event) {
|
|
303
|
+
const json = JSON.stringify(prepareForSerial(event));
|
|
304
|
+
for (const conn of connections) {
|
|
305
|
+
sendToConnection(conn, json);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// Send usage_update (so ESP32 always has fresh usage/reset times)
|
|
310
|
+
// Only send if API usage data is present (fiveHourPercent defined),
|
|
311
|
+
// otherwise the ESP32 would reset its cached values to "no data" sentinel.
|
|
312
|
+
if (usageProvider) {
|
|
313
|
+
const event = usageProvider();
|
|
314
|
+
if (event && event.fiveHourPercent != null) {
|
|
315
|
+
const json = JSON.stringify(prepareForSerial(event));
|
|
316
|
+
for (const conn of connections) {
|
|
317
|
+
sendToConnection(conn, json);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Start ESP32 serial bridge.
|
|
324
|
+
* Detects USB serial ports and opens connections.
|
|
325
|
+
* Call broadcast() to send events to all connected ESP32 devices.
|
|
326
|
+
*
|
|
327
|
+
* Non-blocking: initial device detection runs in background so a hung
|
|
328
|
+
* USB port (stty stuck in kernel I/O) cannot block bridge startup.
|
|
329
|
+
*/
|
|
330
|
+
export function startESP32Serial() {
|
|
331
|
+
// Fire-and-forget initial detection (non-blocking)
|
|
332
|
+
pollForDevices().catch(err => {
|
|
333
|
+
debug('ESP32', `Initial poll failed: ${err.message}`);
|
|
334
|
+
});
|
|
335
|
+
// Poll for new/disconnected devices every 10 seconds
|
|
336
|
+
pollTimer = setInterval(() => {
|
|
337
|
+
pollForDevices().catch(err => {
|
|
338
|
+
debug('ESP32', `Poll failed: ${err.message}`);
|
|
339
|
+
});
|
|
340
|
+
}, 10000);
|
|
341
|
+
// Heartbeat: send current state every 5 seconds so ESP32 stays in sync
|
|
342
|
+
heartbeatTimer = setInterval(sendHeartbeat, 5000);
|
|
343
|
+
debug('ESP32', 'Serial bridge started');
|
|
344
|
+
}
|
|
345
|
+
async function pollForDevices() {
|
|
346
|
+
const ports = await detectESP32Ports();
|
|
347
|
+
// Remove disconnected
|
|
348
|
+
connections = connections.filter(c => {
|
|
349
|
+
if (!c.connected) {
|
|
350
|
+
try {
|
|
351
|
+
c.stream.end();
|
|
352
|
+
}
|
|
353
|
+
catch { /* ignore */ }
|
|
354
|
+
try {
|
|
355
|
+
c.reader?.destroy();
|
|
356
|
+
}
|
|
357
|
+
catch { /* ignore */ }
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
return true;
|
|
361
|
+
});
|
|
362
|
+
// Add new ports
|
|
363
|
+
for (const port of ports) {
|
|
364
|
+
if (!connections.some(c => c.port === port)) {
|
|
365
|
+
const conn = await openPort(port);
|
|
366
|
+
if (conn) {
|
|
367
|
+
connections.push(conn);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Broadcast a BridgeEvent to all connected ESP32 devices via serial.
|
|
374
|
+
*/
|
|
375
|
+
export function broadcastESP32(event) {
|
|
376
|
+
if (connections.length === 0)
|
|
377
|
+
return;
|
|
378
|
+
if (!FORWARDED_EVENTS.has(event.type))
|
|
379
|
+
return;
|
|
380
|
+
const prepared = prepareForSerial(event);
|
|
381
|
+
// Debug: log sessions_list and state_update details for ESP32 troubleshooting
|
|
382
|
+
if (event.type === 'sessions_list') {
|
|
383
|
+
const e = event;
|
|
384
|
+
const summary = (e.sessions || []).map((s) => `${s.agentType}:${s.state ?? '?'}(${s.alive ? 'alive' : 'dead'})`).join(', ');
|
|
385
|
+
debug('ESP32', `→ sessions_list: [${summary}]`);
|
|
386
|
+
}
|
|
387
|
+
else if (event.type === 'state_update') {
|
|
388
|
+
const e = event;
|
|
389
|
+
debug('ESP32', `→ state_update: agent=${e.agentType} state=${e.state}`);
|
|
390
|
+
}
|
|
391
|
+
const json = JSON.stringify(prepared);
|
|
392
|
+
for (const conn of connections) {
|
|
393
|
+
sendToConnection(conn, json);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Send a WiFi provision message to a specific ESP32 device by port path.
|
|
398
|
+
*/
|
|
399
|
+
export function sendWifiProvision(port, msg) {
|
|
400
|
+
const conn = connections.find(c => c.port === port && c.connected);
|
|
401
|
+
if (!conn)
|
|
402
|
+
return false;
|
|
403
|
+
sendToConnection(conn, JSON.stringify(msg));
|
|
404
|
+
conn.provisionSent = true;
|
|
405
|
+
debug('ESP32', `→ ${port}: wifi_provision (SSID: ${msg.ssid})`);
|
|
406
|
+
return true;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Send WiFi provision to all connected ESP32 devices that haven't been provisioned.
|
|
410
|
+
*/
|
|
411
|
+
export function sendWifiProvisionToAll(msg) {
|
|
412
|
+
let count = 0;
|
|
413
|
+
for (const conn of connections) {
|
|
414
|
+
if (!conn.connected)
|
|
415
|
+
continue;
|
|
416
|
+
// Skip if already provisioned or WiFi already configured
|
|
417
|
+
if (conn.provisionSent)
|
|
418
|
+
continue;
|
|
419
|
+
if (conn.deviceInfo?.wifiConnected)
|
|
420
|
+
continue;
|
|
421
|
+
sendToConnection(conn, JSON.stringify(msg));
|
|
422
|
+
conn.provisionSent = true;
|
|
423
|
+
count++;
|
|
424
|
+
debug('ESP32', `→ ${conn.port}: wifi_provision (SSID: ${msg.ssid})`);
|
|
425
|
+
}
|
|
426
|
+
return count;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Get device info for all connected ESP32 devices.
|
|
430
|
+
*/
|
|
431
|
+
export function getESP32DeviceInfo() {
|
|
432
|
+
return connections
|
|
433
|
+
.filter(c => c.connected)
|
|
434
|
+
.map(c => ({
|
|
435
|
+
port: c.port,
|
|
436
|
+
...c.deviceInfo,
|
|
437
|
+
}));
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Wake recovery — close stale file descriptors, force immediate re-poll.
|
|
441
|
+
*/
|
|
442
|
+
export function handleESP32Wake() {
|
|
443
|
+
debug('ESP32', `Wake recovery — closing ${connections.length} stale connection(s)`);
|
|
444
|
+
for (const conn of connections) {
|
|
445
|
+
conn.connected = false;
|
|
446
|
+
try {
|
|
447
|
+
conn.stream.end();
|
|
448
|
+
}
|
|
449
|
+
catch { /* ignore */ }
|
|
450
|
+
try {
|
|
451
|
+
conn.reader?.destroy();
|
|
452
|
+
}
|
|
453
|
+
catch { /* ignore */ }
|
|
454
|
+
}
|
|
455
|
+
connections = [];
|
|
456
|
+
// Delay re-poll 2s to let USB bus stabilize after wake
|
|
457
|
+
setTimeout(() => {
|
|
458
|
+
pollForDevices().catch(err => {
|
|
459
|
+
debug('ESP32', `Wake poll failed: ${err.message}`);
|
|
460
|
+
});
|
|
461
|
+
}, 2000);
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Stop ESP32 serial bridge and close all connections.
|
|
465
|
+
*/
|
|
466
|
+
export function stopESP32Serial() {
|
|
467
|
+
if (pollTimer) {
|
|
468
|
+
clearInterval(pollTimer);
|
|
469
|
+
pollTimer = null;
|
|
470
|
+
}
|
|
471
|
+
if (heartbeatTimer) {
|
|
472
|
+
clearInterval(heartbeatTimer);
|
|
473
|
+
heartbeatTimer = null;
|
|
474
|
+
}
|
|
475
|
+
for (const conn of connections) {
|
|
476
|
+
conn.connected = false;
|
|
477
|
+
try {
|
|
478
|
+
conn.stream.end();
|
|
479
|
+
}
|
|
480
|
+
catch { /* ignore */ }
|
|
481
|
+
try {
|
|
482
|
+
conn.reader?.destroy();
|
|
483
|
+
}
|
|
484
|
+
catch { /* ignore */ }
|
|
485
|
+
}
|
|
486
|
+
connections = [];
|
|
487
|
+
messageHandler = null;
|
|
488
|
+
debug('ESP32', 'Serial bridge stopped');
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Get number of connected ESP32 devices.
|
|
492
|
+
*/
|
|
493
|
+
export function esp32ConnectionCount() {
|
|
494
|
+
return connections.filter(c => c.connected).length;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Get list of connected ESP32 serial port paths.
|
|
498
|
+
*/
|
|
499
|
+
export function getESP32Ports() {
|
|
500
|
+
return connections.filter(c => c.connected).map(c => c.port);
|
|
501
|
+
}
|
|
502
|
+
//# sourceMappingURL=esp32-serial.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"esp32-serial.js","sourceRoot":"","sources":["../src/esp32-serial.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface GatewayStatus {
|
|
2
|
+
available: boolean;
|
|
3
|
+
hasError?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function probeGateway(): Promise<GatewayStatus>;
|
|
6
|
+
/**
|
|
7
|
+
* Run `openclaw doctor` to check gateway health.
|
|
8
|
+
* Returns true if errors are detected (exit code != 0).
|
|
9
|
+
* Runs at a slower cadence than probeGateway (caller should throttle).
|
|
10
|
+
*/
|
|
11
|
+
export declare function checkGatewayHealth(): Promise<boolean>;
|
|
12
|
+
//# sourceMappingURL=gateway-probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway-probe.d.ts","sourceRoot":"","sources":["../src/gateway-probe.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC,CAQ3D;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAiB3D"}
|