Jean-Pierre MartineauandClaude Opus 4.8 61101cf778 Align emoji cell width with the terminal's real rendering
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>
2026-07-06 21:47:10 -04:00
2026-06-21 19:25:03 -04:00

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.

S
Description
No description provided
Readme Apache-2.0
19 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 99.1%
Shell 0.9%