Replace the primitive channel editor that lived inside the config menu with
a dedicated `channels` tool: list the device's slots and, per channel, show a
scannable QR share code, reveal the key, open it in chat, rename/re-key, or
clear it. Create channels four ways — new private (random key), public `#`
(key derived from the name), join-by-key, or import a `meshcore://` link — with
every change written to the device immediately.
- core/channels.py: pure, hardware-free logic (secret derivation, tolerant key
parsing, share-URL round-tripping, channel hash). full_channel_hash exposes
the complete digest; the short channel_hash is its leading byte.
- ui/qr.py: half-block QR rendering (segno), drawn black-on-white so it scans
regardless of terminal theme.
- ui/channels.py: the interactive manager. Channels display by their real name;
reorder rows by dragging with the arrow keys; the key view shows the full hash
with the first byte highlighted.
- ui/tui: a ReorderScreen (grab/move/drop) plus a ctx.ui.reorder surface method.
- tools/channels.py: the tool + `channels list/add/join/import/share` CLI.
- Pin Chat + Channels to the top of the main menu via an explicit category order.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduce a UI surface abstraction (ctx.ui) that tools use for all input
and output instead of touching questionary or the console directly. Two
backends implement it: PlainUi for scripted CLI runs (prints immediately,
byte-for-byte unchanged) and TuiUi for the interactive menu (bounded,
scrollable result windows over a full-screen TuiSession).
The new meshtools/ui/tui package reimplements the slice of questionary the
app used — validated text input, confirm, autocomplete, and selectable
lists — plus framing, progress, and screen management. Swap the dependency
from questionary to prompt_toolkit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>