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>
Trace:
- Auto-path now ends every route at the target's own hash (verified on
hardware: a trace only replies when its destination is the final hop), so
direct neighbors and learned multi-hop routes both resolve correctly.
- Retry the transient "no event received during contacts retrieval" blip and
surface a clean DeviceCommandError instead of a raw traceback.
- Route summary annotates each node with its hash at the command's path-hash
width, wrapping after an arrow when the line is too long.
- Default trace count changed from 5 to 3.
Also includes the in-progress device-config feature (config_io, device_config,
config tool, config editor UI, tests) and related supporting edits.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MeshTools is a Rich+Questionary interactive / Typer-scriptable toolkit for
tuning a MeshCore mesh over a serial companion device, with SQLite-logged runs
and Plotly visualizations. Includes the skeleton (trace, info, history),
TX-power optimization, and a MockDevice simulator (--mock).
Device discovery & selection:
- core/discovery.py: enumerate serial ports (pyserial), flag/sort likely LoRa
hardware by USB vendor id, stable_id for replug-safe identity.
- core/device_store.py: remember the last successfully connected device in
<config_dir>/devices.json (independent of --db).
- core/selection.py: non-interactive resolver (--port > profile > remembered >
sole device > guidance error) for the CLI.
- ui/device_picker.py + menu startup: interactive picker preselecting the
remembered default; banner reflects the choice.
- tools/devices.py: `meshtools devices` lists/marks attached devices.
- AppContext resolves the port and records last-known-good on connect success.
Fixes:
- theme.py: force UTF-8 on stdout/stderr so glyphs don't crash legacy consoles.
- connection.py: friendly message when meshcore is missing; pin meshcore>=2.3.
- trace/tx-optimize: fall back to free-text target entry when the device
reports no contacts (autocomplete requires non-empty choices).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>