- Fix LXMF wire format: standardize on opportunistic [src:16][sig:64][content]
- Fix LXMF signature: sign(dest||src||packed) per spec, remove message_hash
- Fix MsgPack interop: handle both str and bin types for title/content
- Radio defaults changed to Balanced preset (SF9/BW250k/CR5/TX14)
- Messages screen: sorted by most recent, preview with You:/Them:, green unread dot, timestamps
- Status bar: replace LoRa/BLE/WiFi text with signal bars (green=connected, red=offline)
- Home screen: remove Unread info (shown in Messages tab)
- Contacts screen added (Friends tab)
- Identity manager: multi-slot identity support with per-slot display names
- Message store: fix peer hash truncation, SD directory creation, .bak file leak
- Settings: check for updates, active identity display, info diagnostics
- Migrate all screens to LVGL v8.4 widget system
- Non-blocking radio TX (async endPacket via LoRaInterface)
- Live TCP server switching with transient node cleanup
- Fix UI freeze during radio transmit
- Trackball long-press delete, deferred click with debounce
- Pin microReticulum to 392363c, fix list_directory API
- Fix CI build: portable include path, remove hardcoded local path
- Rewrite MessageView with word-wrapped chat bubbles, timestamps,
incoming/outgoing alignment, pixel-based scrolling
- Add IdentityManager for multi-identity support (create/switch/delete,
8 slots max, per-identity display names)
- Fix transport mode: default to endpoint (no rebroadcast) — was acting
as transport node, rebroadcasting every TCP announce over LoRa causing
5-11 second UI freezes per TX. Loop time: 11146ms → 6ms
- Add Transport Node toggle in Settings > Network
- TCP interface now drains up to 10 frames per loop (was 1)
- Reduce LoRa debug polling from 5s to 30s