Skip to content

v2.72.0

Choose a tag to compare

@github-actions github-actions released this 25 Sep 19:12
· 580 commits to main since this release

2.72.0 (2026-09-25)

Features

  • ble: Bluetooth on macOS, over inkwell's CoreBluetooth backend (e86a153), closes mcereal/inkwell#12
  • ble: wait on FromNum's subscribe across turns instead of in the connect (6bcf398)
  • build, test and run the UI natively on macOS (d12166f), closes inkwell#10 inkcell#28
  • devices: honest signal readings, a visible auto-connect radio, safer radio switches (4cbcb9a), closes mcereal/inkwell#39
  • firmware: install nRF52 radios over BLE through their DFU bootloader (6cc8b53)
  • focus: a dialog's answers are reached by where they are, not by counting (9f83bbd), closes mcereal/inkcell#19
  • help: the notes are a body in pixels, under a heading that collapses (1ccfebf)
  • lists: the body travels between windows instead of flicking (9b2484c)
  • overlays: the two questions arrive on layers, over what they are about (af2a001)
  • release: app icon for the macOS and Windows installs (abcfbd0)
  • release: ship a macOS .dmg and a Windows installer (2962f42)
  • serial: find USB serial ports on macOS (7def11d)
  • settings: a row's gutter says how it is changed, not just that it can be (726687b), closes inkcell#3
  • sheets: a node's verbs and a message's faces come up over what they are about (b7bca59)
  • ui: a one-row footer - the screen's verbs and the link, nothing the chrome already says (81b932e)
  • ui: a right-click on a row opens its menu (20d686b)
  • ui: a window's action bar is a toolbar, and back is the arrow (3a73660), closes mcereal/inkcell#36
  • ui: bind desktop shortcuts to commands (562e2b3)
  • ui: draw the focus ring and lift the focused row instead of filling it (a68d642)
  • ui: drive the running client by its keys and look at what it drew (24818d0), closes inkcell#30
  • ui: follow inkcell onto a proportional face (fe34156)
  • ui: leave the on-screen keyboard grid out of a desktop window (42276a8)
  • ui: merge Devices and Status into one Radio tab (c23f673)
  • ui: MESHCLIENT_UI_BACKEND=sdl draws the UI in a window (ec9be92)
  • ui: Messages stands a thread beside its conversations on a wide window (8ce276b)
  • ui: move About radio and Radio actions onto the Radio tab (2551438)
  • ui: move Waypoints into the Nodes tab as a row (e37eeb4)
  • ui: name a node row once and put what else it knows on the line under it (9e2941d)
  • ui: Nodes stands a node beside its roster on a wide window (399061a)
  • ui: place the frame with inkcell's scaffold (92a32c8)
  • ui: put the Mac window's buttons in the tab strip (8762102), closes inkcell#29 inkcell#29
  • ui: route SDL hints through commands (a08a003)
  • ui: set every list by what it is for - inset sections, an accent cursor, tiered type (5b9915e)
  • ui: Settings stands a section beside the section list on a wide window (6acdb56)
  • ui: size label columns and the code caption from measured text (42f2a4e), closes mcereal/inkcell#53
  • ui: tabs, rows and dialog answers are clicked (8daf923)
  • ui: the sheet and the context menu stand off the page; the node's verbs are a menu (96e3cd3)
  • ui: type directly into SDL keyboard drafts (fec131b)
  • ui: verbs in the heading for a pointer, a one-row foot on the device (ba6e616)
  • update: install updates on macOS and Windows (b282f12)
  • update: say which network failure a check or download hit (81c6284)
  • windows: connect to a radio over Bluetooth (275990f)
  • windows: connect to a radio over USB serial (e3153ca)
  • windows: hand TCP sockets to native stream (2de9114)
  • windows: open SDL UI by default (a28098b)
  • windows: support TCP hostnames (a03c44e)
  • windows: TLS and HTTPS, through Mbed TLS (0ef3fbd)

Bug Fixes

  • ble: address review on scan memory and the preferred-radio streak (4cc4205)
  • ble: demote on revoked Bluetooth access, size OTA addresses for macOS (412325f)
  • ble: don't reset the controller over the link a pairing made (2911db1)
  • build: a clean build, under both compilers (887f64e)
  • build: compile inkwell the way this client's own sources are (bb56ccc)
  • build: the no-TLS build must still link (f596271), closes #267
  • clear the no-TLS and MinGW build warnings (20e7cf4), closes #ifdef
  • devtools: every scene verb plays out what it set moving (9fba6d0)
  • devtools: make syncing off end the replay it names (90aaa1f)
  • devtools: refuse a verb row the runner answers first, and keep --delay 0 (4fcddc3)
  • firmware: don't claim a silent server for every network failure (168aafc)
  • firmware: give a silent CDN 15 s, not the image's two minutes (187dcc0)
  • firmware: initialize USB storage writer (d208be9)
  • firmware: offer nRF52 BLE DFU only on BlueZ, and resume only for -p (b59ff81)
  • firmware: pace nRF52 DFU packets from each send, not a schedule (329be07)
  • firmware: say why a download failed instead of repeating it (dfb6c2d)
  • firmware: update UF2 fuzz harness for inkwell (84d216d)
  • firmware: wait for Bluetooth before arming a BLE install (278e62a)
  • firmware: wait out any Bluetooth refusal; CLI honours the staging variable (535bb60)
  • handle first-run Heltec V4 setup safely (b54728c)
  • map: measure the attribution and the node labels (04917ce)
  • nav: hand the snackbar to the next notice when a press dismisses one (2dd3ee4)
  • nav: pin inkstand to the snackbar that waits out the press (59b01ed) (ec095aa)
  • net: a broker refusal must not log as a success (52221b9)
  • overlays: declare the copy, and keep help the topmost thing (041653e)
  • release: close a running client before the Windows uninstall (e361eaa)
  • release: delete each rpath once; expect a binary on macOS in the updater test (05eb271)
  • serial: wait for the bind's tty on the tick, not in the connect (6470cb0), closes mcereal/inkwell#18
  • settings: check a field id against the table before narrowing it (e19f250)
  • settings: keep the stepper when a segmented control falls back to a word (39496a5)
  • settings: track reboots across handshake resets (c04c74e)
  • setup-macos syncs stale submodules; AGENTS.md names the Mac path (17a0834), closes inkcell#28
  • setup: bootstrap WSL without make (318a097)
  • setup: support Windows worktrees via WSL (52d8e96)
  • store: say when the trend logs of a swapped radio could not be dropped (f95944b)
  • ui: a backend that will not open falls back, from review (7ff14ba)
  • ui: a click stands armed deletes down and waits for a current frame (32369f6)
  • ui: a frame request joins the one already armed (3c28e83)
  • ui: dismiss context menu before host text (34b0c4d)
  • ui: drop a remote node's pending edits when leaving it from any tab (4397bb8)
  • ui: find the open thread's row in the list beside it by what it is (9e17d36)
  • ui: keep a list's cursor-row verbs off the pointer heading (26dcf08)
  • ui: keep the places cursor when the Nodes tab is not showing (f57bcba)
  • ui: make the Status cards' buttons clickable (3ddab42)
  • ui: mark a node row's distance approximate when either fix is rounded (708f7fc)
  • ui: never draw a screen transition under the partial-redraw band (adc7059)
  • ui: new data under a right-click menu puts it down (dd45473)
  • ui: pin inkcell so a focused card verb clears the card's edge (f9b19cc)
  • ui: pin inkcell so help's back arrow takes a click (89b206d) (1f56690), closes #57
  • ui: pin inkcell so the focus ring jumps between Radio tab cards (77b63a3) (aaf9f43)
  • ui: pin inkcell to the review fix for the card verb clearance (207776b) (d0ea245)
  • ui: preserve context menu order (9cceeb7)
  • ui: take the slide offset from the scaffold's transition after the merge (5a2e416)
  • ui: the control socket removes nothing it did not create (a0a001b)
  • ui: three headers the shim sweep took that were not shims (e3e1fab)
  • update: offer no macOS update where the bundle's folder is read-only (3c97467)
  • update: replace the whole bundle on macOS; UTF-8 code page on Windows (66ce9d2)
  • windows: check the client's printf-like formats against the CRT's dialect (5d249ef)
  • windows: fail setup check for stale submodules (f547f1a)
  • windows: honor configured SDL default for auto backend (cf82143)
  • windows: make resolver lifecycle nonblocking (340bb3d)

Documentation

  • actions: why mesh_ui_action_bar_goes_back() is this client's (603c9dd), closes mcereal/inkcell#23
  • correct the map after the inkcell extraction (f26799f), closes #include
  • re-render the listing screenshots (5a6e599)
  • re-render the listing stills for the one-row foot (933ad30)
  • the paths the extraction cleanup missed (60bb611), closes #258 #258
  • transport: say that inkwell depends on this port's VMIN (398f5de)
  • ui: the list roles and the one-row footer; refresh the listing stills (4eadad5)
  • windows: plaintext MQTT works; TLS and HTTPS fetch remain (8d66cb1)

Code Refactoring

  • app: drive the control socket through a host, not the controller (86af729)
  • app: use inkstand's control socket (9965abf)
  • ble: stand the BLE transport on inkwell's central (5f72f80), closes mcereal/inkwell#11
  • ble: use inkwell connection intervals (08685ca)
  • devtools: play ui_capture's scenes on inkstand's runner (8b5ff3c), closes #317
  • devtools: split the scene runner out of ui_capture's main.c (c611e3d)
  • firmware: fetch the image through inkwell's net/zip_fetch.h (725bbcf)
  • firmware: use inkwell image codecs (07f1e79)
  • firmware: use inkwell USB storage (ed6fbd9)
  • give inkwell the five things here that were never about a mesh (f462d1e)
  • i18n: word TCP and MQTT failures through mesh_net_reason_format() (3b26681)
  • keyboard: the grid is inkcell's; what it is for stays here (c85f511)
  • mqtt: use inkwell client (21aa6ca)
  • nav: answer the confirm sheet through inkstand's nav/dialog.h (469b598)
  • nav: keep the snackbar's queue through inkstand's nav/toast.h (41c5c42)
  • nav: split the snackbar's queue from the nav (8247c7b)
  • nav: split the two-answer dialog from the confirm sheet (04e5ba1)
  • net,ui: the MQTT proxy reports a reason, not a sentence (a78379e)
  • net: the TLS client is handed its roots and the fetcher its name (8d747af)
  • net: the TLS session and the HTTPS request are inkwell's (1d17cb8)
  • serial: take the USB serial ports from inkwell's io/serial.h (be3401d), closes mcereal/inkwell#18
  • settings: describe every field through inkstand's form descriptor (33327da)
  • settings: parse and print settings through inkstand's form codec (75d9041)
  • settings: split the field descriptor from this client's field table (ad88a7c)
  • settings: split the number scale and the choice set from the field table (de14ec5)
  • settings: split the text codec from this client's spellings of it (e8c19ed)
  • settings: step and place presets through inkstand's form scale (d34869d)
  • stand on inkwell (c40dadb)
  • store: keep both logs through inkstand's journal (66065f0)
  • store: keep the preferences' lists through inkstand's recently-used list (b4e0590)
  • store: one journal under the archive and the trend log (503286b)
  • store: one recently-used list under both of the preferences' lists (8becb2a)
  • store: read the cache through inkstand's key table and field reader (8ae7802)
  • store: split the key-table mechanism from the cache's keys (84a2981)
  • store: use inkwell record file primitives (7ea0ca5)
  • tcp: use inkwell connector (b3d6e4f)
  • transport,i18n: the TCP link reports a reason, not a sentence (03a900d)
  • transport: the stream link is the parser and the session over inkwell's stream (4273690)
  • ui: declare commands in action tables (9693dc4)
  • ui: dispatch context menu commands (75cde8d)
  • ui: dispatch semantic commands (cc9c0bb)
  • ui: drop the path shims and include the inkcell headers (83e1f6b)
  • ui: follow inkcell's drawing state off the framebuffer (7c987f9)
  • ui: hold a settings field id in 16 bits wherever it is kept (0e7c957)
  • ui: introduce semantic command foundation (58f7f28)
  • ui: present through inkstand's frame scheduler (4c7fab0)
  • ui: retire inkcell_compat.h and spell the inkcell names (ae03228), closes #defined
  • ui: split the frame scheduler out of the controller (b411e47)