`ruff format .` across the repo: 153 files, no behaviour change. This is the
second gate CONTRIBUTING.md promises, and until now it reported 154 files needing
reformat — so a first contributor ran the command the guide told them to run and
could not tell their own diff from the background.
Landed on its own, with nothing else in it, because a whole-repo reformat is only
safe to skip past in blame if it is provably nothing but layout. It was checked
that way rather than assumed: every changed file was formatted in memory and
compared by full `ast.dump()`, and 152 of 153 come out structurally identical
(the one exception was a docstring opening on a quote character, fixed in the
commit before this one). The string and comment token streams were diffed
separately, so a quote flip or an edited comment could not hide inside a
re-layout — five quote-style normalisations and sixteen implicit-concatenation
joins, all value-identical, and one commented-out line gaining the space after
its `#`. `meshterm specimen` is byte-identical on both platforms, and the suite
is 1888 green, gallery gate and `test_theme16` included.
What actually changed, in order of how much of the diff it is: wrapped calls and
signatures rejoin onto one line where they fit inside the hundred columns; the
magic trailing comma expands what it is there to expand; complex slices gain
their spaces (`[len(noise) :]`); a few redundant parens go. The tables that are
laid out to be read were fenced in the previous commit and are untouched here.
The aligned trailing-comment column is gone from about ninety lanes that were not
fenced — including the `heat.*` ladder in `MESH_THEME`, which cannot be fenced
where it sits. Every comment stays on the entry it describes, so nothing there
reads wrong; it just no longer lines up.
Add this commit to `.git-blame-ignore-revs`, which follows immediately.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The last 122 `D205` sites, which takes `ruff check .` to zero.
Same shape as the package pass and just as additive: these were a paragraph
with no summary, so each one gains a plain sentence saying what is being
asserted, and every word that was there moves down into the description. The
dense ones benefit most — `test_pathline`'s 23, where "A seam is one cell, not
two" now stands alone and the chevron mechanics explain it underneath, and
`test_tui`'s wide-glyph repaint test, whose seven lines on prompt_toolkit's
relative cursor now sit under the one line that says what the test pins.
Four module docstrings (`test_advert`, `test_gallery`, `test_platforms`,
`test_repeater_admin`) opened with "X tests: a, b, and c" and now name the
subject on the first line with the list below it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`ruff check --fix` over the whole tree, ahead of putting the linter in CI:
1977 mechanical fixes, overwhelmingly `Optional[X]` → `X | None` (1186 in the
package alone) and the quoted annotations that `from __future__ import
annotations` already made unnecessary, plus import sorting and unused imports.
Nothing here changes behaviour — the suite is 1885 green before and after.
Four findings were real rather than stylistic and are fixed by hand: a dead
`cells` range in `MapCanvas`, a dead slot dict in the heat-ladder test, a
`ProgressScreen` task handle nobody read, and a tab loop binding a `label` it
never used. The two `F821`s were quoted forward references to names imported
inside their function bodies — now declared under `TYPE_CHECKING`, which keeps
`test_performance`'s local import (it guards the startup import graph) while
letting the linter resolve the name.
412 findings remain and are deliberately untouched: they need a decision about
the rule, not an edit to the code.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three independent consistency passes:
1. **Message paths: unknown relays as grey full-hash**
The message-paths dialog showed unnamed relay hops as a single lit byte (e.g.
`e8`). Now they render at the device's path-hash-mode width, muted grey, and
annotated with their addressed byte — `e839f2 (e8)` — so the rows stay
readable and cross-reference the route graph's byte labels (matching named
hops' trace presentation). Added `hash_as_name` flag to path_text widget.
2. **Dialogs: multi-layer compositor + backdrop for empty stack**
Opening a confirm over a floating popup used to stretch that popup to
full-frame (the single-float compositor's bug). Now the compositor maintains
a pool of _MAX_DIALOG_LAYERS=8 centered-box floats, each rendering one layer
above the background — so a popup and its confirm both stay their own size.
Also: button_dialog/typed_confirm/autocomplete now float over a blank base
when the stack is empty (via _run_dialog_screen), guaranteeing popups render
as small boxes on an empty stack, not full-frame chrome. Simplified
message_dialog to delegate its backdrop logic to button_dialog.
3. **Data-loss dialogs: red `destructive` tier**
Added a second caution tier to the dialog API: danger=True stays amber
(disruptive: discard edits, reboot), destructive=True is red (irreversible
data loss). Updated: single-record delete, channel "clear slot", courier
"clear finished" (new confirm), and startup "remove device" (splash confirm).
Per UX spec: bulk/irreversible deletions gate behind typed_confirm (also red);
single-record delete is a red Cancel/[verb] button dialog.
All changes are backward-compatible. Full suite: 793 tests pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A one-line result like "✓ flood advertisement sent" used to open the
full scrollable result window — a huge frame for a single sentence.
TuiUi.present() now collapses small, text-only output (at most 3 lines,
none wider than 76 cells) into a centered popup with an OK button,
floating over whatever screen is beneath; tables, long errors, and
multi-line output keep the window. Fixed centrally in present(), the
upgrade covers every such site at once: adverts, clock sync, backups,
key import, "applied N changes", tool failures, and future ones.
ButtonDialog learns to render a pre-styled (multi-line) Text prompt so
note markup survives into the popup, and the border echoes the message's
strongest tone (err > warn > accent). When the popup would sit on an
empty stack (a tool run from the popped main menu), a blank base frame
is pushed beneath it first — the same trick as the reconnect dialog —
so it draws as a floating box, not as the base.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>