Files
James RichandClaude Sonnet 5 19bca6bb44 feat(webApp): add Web Serial transport for USB/serial connectivity
Wires InterfaceId.SERIAL into WasmJsRadioTransportFactory via a new
WasmJsSerialTransport (StreamTransport backed by the Web Serial API's
readable/writable streams), replacing the previous "not supported on
web yet" error. core:network's serial/ package isolates the raw
navigator.serial JS interop the same way core:ble's WebBluetoothApi.kt
isolates Web Bluetooth, plus a WebSerialPortRegistry that mints a
synthetic id for each granted JsSerialPort (Web Serial ports carry no
persistent identifier of their own) and exposes only a public
GrantedSerialPort(id, vendorId, productId) across the core:network/
feature:connections module boundary -- never the internal port type
itself.

feature:connections's UsbScanner interface gains two default, no-op
methods (needsExplicitDeviceRequest/requestNewDevice) so JVM/Android
are unaffected; WasmJsUsbScanner implements both, since Web Serial
needs an explicit requestPort() gesture to discover a device the page
hasn't seen before, unlike ambient OS-level enumeration on desktop.
DeviceList's USB section renders an "Add serial device..." action only
when a platform supplies that callback.

Surveyed a WebSocket-based transport for WiFi-connected nodes as an
alternative/addition: not viable currently, since Meshtastic firmware
has no WebSocket listener for the device-facing protobuf protocol
(port 4403 is raw-socket-only) -- tracked in the workpad, not
implemented.

Verified: full spotlessApply/spotlessCheck/detekt/assembleDebug/test/
allTests baseline passes repo-wide, and :webApp:wasmJsBrowserDistribution
(the production Kotlin/Wasm link step that has hit a compiler-backend
crash earlier in this effort) succeeds cleanly with this transport's
new @Single registry and StreamTransport subclass. Confirmed live in a
browser: the button renders, and clicking it invokes
navigator.serial.requestPort() with no SecurityError -- the
transient-activation gesture chain holds. Actually granting a device
and completing a connect/reconnect cycle needs a human at a native OS
picker dialog, which browser automation can't drive; not performed
this pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 10:22:33 -05:00
..