pymc_core's ContactStore is memory-only, so every bridge restart forgot
every contact and DMs failed with ERR_CODE_NOT_FOUND until the peer was
heard advertising again. Snapshot the store to contacts.json after every
mutation and reload it at startup, alongside the identity the bridge
already persists.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Newer MeshCore firmware sends discrete ACK payloads longer than 4 bytes
(4-byte CRC first, then extras). pymc_core's AckHandler requires exactly
4 bytes and silently drops them, so DMs sent through the SPI bridge never
show delivery confirmation. Patch process_discrete_ack at bridge startup
to take the leading 4 bytes as the CRC, matching pymc_core's own
path-bundled ACK parsing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Expose an SPI-attached MeshCore radio (uConsole AIO, Waveshare HATs) to
MeshTerm over the companion protocol on local TCP. A single stdlib-only
file that is both a plain-text setup menu and the bridge process: it finds
the pymc_core runtime and re-execs the bridge under it, offers run-now /
install-as-a-service / uninstall, and can add a [profiles.bridge] block so
the endpoint shows up in MeshTerm's device picker.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>