Add TCP alongside serial and BLE as a first-class companion transport, end to
end: discovery/connection/selection learn a tcp: stable_id and host:port target,
--tcp and TCP config profiles reach a WiFi board or network proxy, and a network
companion -- which isn't discoverable -- is rebuilt into the picker from its
remembered endpoint.
Device picker gains the network-device affordances:
- "Add a network device" prompts for host:port, smoke-tests it, and remembers it.
The row is marked "- experimental" in the cautionary hue.
- Delete on a network row opens a chromeless Cancel/Remove confirm (Cancel left,
Remove right and default: Enter removes, Esc cancels), then DeviceStore.forget
prunes it and re-draws the list. Serial/BLE rows stay inert.
- The "Del remove" footer atom now follows the highlight, surfacing on the box's
bottom border only while the cursor sits on a deletable row; the box is sized
to the fullest footer so it never widens mid-navigation.
Folds in the accompanying courier, channels, and config refinements built along
the way. Screens stay readable at 72 cols; full suite green (745 tests).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Scripted runs print straight to the terminal, so a tool's heavy Rich
framing — a Panel's border, a Table's full box, Typer's boxed help
panels — is chrome between the reader and the data. Lighten it to a
middle ground: PlainUi de-frames tool output (Panel/Table titles become
bold-accent headings, tables keep just a single rule under their header),
and the Typer help drops its rounded Options/Commands/Error panels for
the same heading-over-content shape while keeping rich mode's colour
(yellow usage, cyan options, green switches). Functional, easy to scan,
none of the interactive menu's weight. The full-screen TUI is untouched.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Enforce one voice across every screen: column and section headers are
UPPERCASE, menu items are Capitalized buttons, and short descriptions
drop their trailing period (with real ellipses instead of "...").
Tools gain a display `title` separate from their kebab-case CLI name,
so a menu item now reads exactly like the screen it opens ("Device
configuration" opens Device configuration) and result windows inherit
the same name. Every sub-screen backs out via a "Back" row below a
blank separator (the config editor was missing both; its Close is now
Back, spelling out the discard when changes are staged), while the main
menu and device picker keep "Quit". Panel and dialog titles now wear a
brighter tint of their border colour via new title.* theme styles.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Companions can now be reached over Bluetooth as well as USB. Rather than
a parallel BLE path, this generalizes the existing serial abstractions so
a device is identified by a transport (serial | ble) plus a target (COM
port or Bluetooth address); every feature rides the same Device interface
and works over either link unchanged.
- discovery: DiscoveredDevice gains transport/address/name and
transport-aware stable_id/label/confidence/target; discover_ble_devices
scans for MeshCore* adverts via bleak, discover_all merges both.
- connection: MeshCoreDevice opens create_ble vs create_serial by
transport; new link_present() liveness (OS port enumeration for serial,
the BLE client's is_connected flag for Bluetooth); is_connection_lost
recognizes Bleak errors and BLE transport callbacks; probe_device is the
transport-aware smoke test.
- disconnect: the session watcher polls transport-neutral link_alive(), so
a dropped BLE link raises the same reconnect dialog and auto-resume as an
unplugged cable; reconnect rebuilds the same endpoint by address.
- selection/context/store/profiles: --ble address, remembered BLE default,
and BLE device profiles all resolve to the right transport.
- UI/CLI: startup picker scans both transports behind a spinner and tags
Bluetooth companions; `devices` lists them (--no-ble to skip); global
--ble/--ble-pin flags; README and example config updated.
Validated on hardware: discovery, connect, reconnect, and channel
messaging (send + receive) over BLE.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Watch the companion link while the menu runs; if it disconnects, float a
centered dialog with a spinner and a single Abort button while a
background task retries the connection. The dialog dismisses itself the
moment the device returns, so the user's only action is to give up:
Enter aborts, and Esc is deliberately inert so a stray keypress can't
drop the session while a replug may be a second away.
Give every popup dialog the same cyan reverse-highlight button. This
adds a "selected" theme style (and "err.reverse"): Rich silently renders
a style string that mixes a theme name with an attribute ("reverse
brand") as plain text, so the reverse is baked into a single-name theme
entry instead. Center the button chips with manual padding rather than
Text(justify="center"), which strips a styled span's trailing whitespace
and left the label hugging the fill's left edge.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rename the package directory, imports, brand strings, env-var prefixes,
console-script entry point, and the config/data dir (~/.config/meshterm).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>