61101cf77856b5c82359821d318bd04e2136f4e5
Rich counts a VS16 emoji like the sun as 2 columns (Unicode TR51), but many terminals paint it as 1, so padded content and the panel border that follows it landed a column early. Add a startup calibration that decides the VS16 width in order of trust: an env override, a fingerprint of split-renderer terminals (VS Code, Windows Terminal) whose PTY cursor accounting disagrees with what they paint, then a live cursor probe where that is valid. When the width is 1, patch Rich's string measurement so every panel, table, and chat bubble lines up while genuine wide emoji stay 2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MeshTools
A modern, extensible command-line toolkit for tuning and exploring a MeshCore mesh through a serial-connected companion device.
MeshTools is interactive by default (a Rich + Questionary menu) and fully scriptable (every menu option is also a Typer subcommand). Every run is logged to SQLite and can be turned into interactive HTML visualizations.
Features
| Feature | Status | What it does |
|---|---|---|
| Trace | ✅ skeleton | Run repeated path traces to a target and aggregate per-hop SNR. |
| Device info | ✅ skeleton | Show the connected companion device's identity and radio config. |
| Node list | ✅ working | List this node and its known contacts — full public keys with the path-hash prefix highlighted. |
| Device config | ✅ working | View and change every setting (name, radio, behavior, experimental), with TOML backup/restore, channels, and gated destructive ops. |
| Device discovery | ✅ working | Enumerate serial devices, pick one interactively, and remember the last good default. |
| History / DB | ✅ skeleton | Every tool execution and measurement is persisted and queryable. |
| TX-power optimization | ✅ working | Sweep transmit power (coarse + refine), converge on the best signal, optionally apply, render an interactive chart. |
| Link budget | ✅ working | Predict time-on-air, receiver sensitivity, range, and duty-cycle/dwell headroom for a radio config — offline, no radio needed. |
| Chat | ✅ working | Live full-screen channel and direct messaging — a scrolling transcript with a pinned input line where sent and received messages stream together. Every message is logged to SQLite, unread counts show in the menu header, and chat send/history/list script the same from the CLI. Channels are picked here; edit them in config. |
| Passive monitor | ✅ working | Toggle a non-blocking background logger that records every overheard advert/telemetry (SNR, RSSI, location) to a longitudinal history while you keep using the app; on/off is remembered between sessions and live packet counts show in the menu. |
| Link health | ✅ working | Compare a target's recent traces to its rolling baseline and flag SNR/reliability regressions, end-to-end and per hop. |
| Route map | ✅ working | Aggregate trace history into an interactive route-stability graph — which links are stable, which the mesh flaps between, with churn metrics. |
| Path optimization | 🚧 planned | Discover and score mesh paths from neighbors outward. |
| Visualizations | 🟡 partial | Plotly TX-sweep chart (HTML) done; pyvis mesh graph + time-series planned. |
Install
pip install -e ".[dev]"
Python 3.10+ is required (matching the meshcore library).
Usage
# Interactive menu (default)
meshtools
# Scripted: every menu option is also a subcommand
meshtools trace --target Alice --samples 10 --profile yagi
# Force a route through specific repeaters (MeshCore-app style): comma-separated
# contact names and/or hex key prefixes, mixed freely. Blank lets the device route.
meshtools trace --target Alice --path "3d,f2,3d"
meshtools trace --target Alice --path "3d,Bravo-Repeater,f2"
meshtools tx-optimize --target Alice --samples 6 --step 3 --apply
meshtools info
meshtools history
# Messaging: live chat in the menu, or scripted from the CLI
meshtools chat # interactive: pick a conversation, chat live
meshtools chat send --to Alice "on my way" # direct message
meshtools chat send --channel 0 "net in 5" # channel broadcast
meshtools chat history --to Alice
meshtools chat list
# Device configuration: view, set, back up, restore
meshtools config # show all current settings
meshtools config set radio_sf 9 # change one setting
meshtools config backup node.toml # archive every setting to TOML
meshtools config restore node.toml --dry-run
# No radio attached? Use the built-in simulator for development.
meshtools --mock trace --target Alice
Architecture
MeshTools is layered so features are added by dropping a single file in meshtools/tools/:
cli.py Typer app; no subcommand -> interactive menu
context.py AppContext (console, config, repository, device) dependency container
core/ Domain: models, config + device profiles, connection abstraction (+ mock)
tools/ Pluggable "menu options"; each self-registers and gets logging for free
services/ Algorithms (trace aggregation, tx search, path exploration) — no UI
persistence/ SQLite schema, repository, structured logging
ui/ Rich theme/widgets + Questionary menu
viz/ Plotly / pyvis renderers -> HTML & PNG
Adding a feature means subclassing Tool, decorating it with @register, and
implementing run(). The same registry builds both the CLI and the menu, and the base
class wraps every execution in a logged runs row automatically.
Languages
Python
99.1%
Shell
0.9%