Every Python file names its licence with an SPDX identifier

Apache-2.0 does not require per-file headers, but a file lifted out of the tree carried no marking at all. One comment line, first (or right after a shebang), on every .py under meshterm/, tests/, packaging/ and scripts/, plus the extensionless SPI bridge; tests/test_spdx.py keeps a new file from landing without one.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Jean-Pierre MartineauandClaude Fable 5.1 committed 2026-09-13 13:09:18 -04:00
1 parent f16a7c4738
commit c9f5a71ce7
235 files changed
+291

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""MeshTerm is a full-featured TUI-based MeshCore client for your terminal.
Supports USB, Bluetooth and TCP companion connection. For Windows, macOS and Linux.
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Enable ``python -m meshterm``."""
from .cli import main
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Typer entry point.
Global options are parsed once in the callback, which builds the shared
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The application context: a small dependency container passed to every tool.
``AppContext`` owns the shared, expensive singletons (console, settings, repository,
+1
View File
@@ -1 +1,2 @@
# SPDX-License-Identifier: Apache-2.0
"""Core domain layer: models, configuration, and the device connection abstraction."""
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Persistence for remembered remote-node admin passwords.
The remote-admin optimizer logs in to a repeater to tune its TX power; storing the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Persistence for the background-advert schedule.
MeshTerm announces the connected node on a cadence — a zero-hop (direct) advert for the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""THE way MeshTerm replaces a file it owns: all of the new contents, or none of them.
Every store under ``core/`` keeps its state in one file that it rewrites whole. Writing
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Reading the device's channel slots back off the radio.
One configured channel slot (:class:`ChannelSlot`) and the two reads that discover them.
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Persistence for channels created through MeshTerm, so they survive a device that forgets.
Most companions keep their own channel table in firmware, so MeshTerm reads channels live from
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Pure channel logic: secret derivation, MeshCore share-URL round-tripping, and decrypt.
A MeshCore channel is a name plus a 16-byte shared secret. *Public* channels (whose name
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Machine setup and named device profiles.
Settings are read from a TOML file (default ``~/.meshterm/config.toml``) and may
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""TOML backup and restore for device configuration.
A backup captures every registry setting's current value plus experimental custom
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Device connection abstraction.
Services and tools depend only on the :class:`Device` interface, never on the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
r"""Installing and selecting a console font on Windows, for one user, without admin.
The classic Windows console does no font fallback: a character its configured font lacks
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Rating contacts by how much they are worth a slot in the device's contact table.
A companion's contact table is finite, and a mesh fills it with whatever adverts happen to
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Persistence for contacts heard through MeshTerm, so they survive a device that forgets them.
Most companions keep their contact table in firmware, so MeshTerm reads contacts live from the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Persistence for the Courier: the store-and-forward outbox.
The Courier (see :mod:`meshterm.services.courier`) queues direct messages for contacts
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Declarative registry of every settable device configuration value.
Each :class:`SettingSpec` describes one tunable setting: how to read its current value
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Persistence for confirmed companion devices.
Every device that has ever spoken the MeshCore protocol to us successfully is remembered
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Companion-device discovery across transports (serial + Bluetooth LE + TCP).
Discovery enumerates the companion kinds that can be *found* automatically:
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Typed events carried by the always-on mesh event hub.
These are the domain-level events that flow from the connected companion device out to
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The exit statuses ``meshterm`` returns, and what each one means.
A scripted run's *return value is its report*: the CLI says what happened in plain
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""What an overheard frame is *addressed to* — the packet body nobody else parses.
The companion's RX packet log hands every overheard frame to the meshcore library, which
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Pure geographic helpers for the terminal map: Web Mercator, tiles, and viewports.
This module is deliberately I/O-free and rendering-free so it can be unit-tested without a
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""One interactive MeshTerm per data directory, and a clear answer when you want two.
Every copy of MeshTerm on a machine reads and writes the same ``~/.meshterm`` — a
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Domain models shared across services, tools, persistence, and visualizations.
These are plain dataclasses with no I/O dependencies so they can be constructed by the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Persistence for muted channel notifications.
Some channels carry traffic you want *recorded* but not *notified* about — an automated
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""A tiny, dependency-free Mapbox Vector Tile (MVT) decoder.
Vector tiles are Protocol-Buffer messages (spec: github.com/mapbox/vector-tile-spec). Rather
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Declarative registry of MeshTerm's own preferences, and the TOML file they live in.
The distinction this module draws is between the three kinds of "setting" the app already
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The remote-node settings catalog: what a repeater can be asked and told over the mesh.
Repeaters and room servers are administered through their text CLI — ``get``/``set``
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Persistence for remote-node admin state: last-read settings and CLI history.
Reading a repeater's configuration costs one paced mesh round trip per value, so the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Non-interactive device selection: turn discovery + memory into a chosen port.
This is the logic used on the scripted CLI path (and as the fallback when the interactive
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Persistence for device settings changed through MeshTerm, so they survive a forgetful device.
Most companions keep their configuration in firmware, so MeshTerm reads settings live from the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The arithmetic a trace is sized and flagged by.
Two pure functions and the four constants behind them: how a per-hop path-hash width is
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The shared transmit clock: how long ago we last put something on the air.
MeshTerm has always paced its own bursts — a trace waits between samples, a TX sweep
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Persistence for the Watchtower: watched nodes, their rules, and the alert log.
The Watchtower (see :mod:`meshterm.services.watchtower`) is a passive sentinel: the user
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Private handles on the Windows DLLs, because ``ctypes.windll`` is shared with everyone.
``ctypes.windll.kernel32`` is a cache. Every caller in the process gets the *same*
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Reopening the session in Windows Terminal, which is where MeshTerm looks like itself.
MeshTerm is drawn with emoji icons, braille charts and powerline path chips. Whether any
+1
View File
@@ -1 +1,2 @@
# SPDX-License-Identifier: Apache-2.0
"""Persistence layer: SQLite schema, repository, and structured logging."""
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""SQLite database bootstrap and schema.
The schema is intentionally generic: a central ``runs`` table records every tool
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Logging setup: a plain text file you can open, and a console that stays out of the way.
Two sinks. The console handler is Rich-formatted and shows what a person watching the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Repository: the single gateway between the app and the database.
Tools and services never issue SQL directly; they call typed methods here. This keeps
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The platform seam: a frozen spec every consumer binds to once, at boot.
MeshTerm runs two flavours from one codebase — the regular desktop terminal and the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Algorithm layer: pure logic for tracing, TX search, and path exploration.
Services may depend on :mod:`meshterm.core` (the :class:`~meshterm.core.connection.Device`
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The background-advert scheduler: keep this node announced without anyone asking.
A quiet session-long task that sends a zero-hop (direct) advert and a flood advert on
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Fetch and cache OpenStreetMap vector tiles for the terminal map.
This is the only networked part of the map. It resolves a tile source's (versioned) tile-URL
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The battery poller: keep the status bar's fuel gauge current, quietly.
A session-long task that reads the connected companion's battery voltage on a slow
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The chat service: message persistence, unread tracking, and the send path.
Like the passive monitor, this service is not a listener in its own right — the always-on
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The PicoCalc's console font: remember what was there, switch, put it back.
The handheld draws to a Linux virtual terminal, and a VT loads exactly one font for the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The Courier: store-and-forward delivery for the outbox.
A session-long background loop over the :class:`~meshterm.core.courier_store.
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The session's device-state cache: read the radio once, reuse it everywhere.
Opening a screen used to re-read the same stable facts from the companion every time —
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The always-on mesh event hub.
The hub is the single seam between the raw companion-device event stream and everything
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Collecting the mesh's located nodes into map markers.
One list, three surfaces: the ``map`` tool's full-screen map, the node page's preview minimap,
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Recover the paths a chat message rode in on, from the stored packet log.
The radio's RX log records every frame it decodes — including the relay path each one
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The optional Shift-state watcher behind the PicoCalc F-key lane's live flip.
The PicoCalc keyboard's MCU translates Shift+F1..F5 into plain F6–F10 keycodes, so the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The passive-monitor history logger.
Passive monitoring records every advert/telemetry frame the companion overhears to the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Multi-path probing: measure candidate routes to a target and rank what actually works.
The topology graph (:mod:`~meshterm.services.topology`) proposes routes from *received*
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Walk records: how a completed trace is measured and scored for the trophy case.
A *walk* is one trace whose route starts and ends at our node — we transmit the first
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The observed mesh topology: a link graph distilled from every path we ever received.
MeshCore never tells us the network's shape outright, but almost everything we *receive*
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Repeated-trace execution with duty-cycle pacing, plus trace parsing helpers.
:func:`run_traces` is the measurement primitive the TX optimizer and the path probe
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Remote-admin TX-power optimization.
This tunes the transmit power of a *remote* node we have admin rights on — the node
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The Watchtower: passive rules over what the hub already hears, raising alerts.
A sentinel, not a prober — it transmits nothing and asks the radio for nothing. It rides
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Pluggable tools (menu options / CLI subcommands).
Importing this package eagerly imports every tool module so that each one's ``@register``
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The About MeshTerm tools: the four written pages in the menu's last section.
*About MeshTerm*, *About the author*, *Join Discord*, *Support MeshTerm* — in that
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``advert`` tool: announce this node to the mesh, straight from the main menu.
Opens the Send advert flow (see :func:`meshterm.ui.config_editor.send_advert`) — a
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The tool plugin contract and registry.
A *tool* is one menu option / CLI subcommand. Subclass :class:`Tool`, decorate it with
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``channels`` tool: create, join, and manage mesh channels.
Interactively it opens a full-screen channel manager (see :mod:`meshterm.ui.channels`) — a
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``chat`` tool: channel and direct messaging over the mesh.
Interactively it opens a conversation picker and then a live, full-screen chat (see
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``config`` tool: every device setting, and the operations on the box itself.
Interactively it opens the Device config page (see :mod:`meshterm.ui.config_editor`) —
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``contacts`` tool: list the contacts this node knows about.
The menu opens the sortable Contacts screen, which leads with our own node; the CLI
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``courier`` tool: store-and-forward messaging for contacts that aren't there yet.
Interactively it opens the outbox screen (see :mod:`meshterm.ui.courier_screen`):
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``dashboard`` tool: the live mesh overview, at the top of the Watch section.
Opens the full-screen dashboard (see :mod:`meshterm.ui.dashboard_screen`): the two-hour
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``devices`` tool: enumerate attached serial and in-range Bluetooth companions.
Discovery never opens the radio — it only lists what is attached or advertising. This is a
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``info`` tool: show the connected companion device's identity and radio config."""
from __future__ import annotations
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``livefeed`` tool: every packet as it arrives, right under the dashboard.
Opens the full-screen live feed (see :mod:`meshterm.ui.livefeed_screen`): the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``map`` tool: plot the mesh's located nodes on an OpenStreetMap terminal map.
Nodes that share their location in adverts are collected from the passive-monitor history
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``monitor`` tool: a bounded foreground capture of what the mesh is saying.
Passive monitoring records every advert and telemetry frame the companion overhears —
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``preferences`` tool: how MeshTerm itself behaves.
Interactively it opens the Preferences page (see :mod:`meshterm.ui.preferences`), which
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The Trophy case tool: the record-setting walks the trace tools have turned up.
The menu face opens the browser (:mod:`meshterm.ui.records_screen`): every discipline's
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``repeater-admin`` tool: set up remote repeaters and room servers over the mesh.
Interactively it opens the repeater-admin flow (see :mod:`meshterm.ui.repeater_admin`):
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``timemachine`` tool: explore everything the recorder ever heard.
Opens the Time Machine (see :mod:`meshterm.ui.timemachine_screen`): pick the whole mesh
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The trace tools: path traces, live in the menu, one-shot on the CLI.
A trace is one walked path — the protocol has no destination field, so "target" is
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``tx-optimize`` tool: tune a remote node's TX power for the best signal at a target.
You force a path (just like ``trace``) ending at the **target** node where SNR is
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``walk`` tool: the mesh's observed shape, explored one node at a time.
Opens the full-screen Mesh walk (see :mod:`meshterm.ui.walk_screen`): a walkable
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The ``watchtower`` tool: a passive sentinel over the nodes you care about.
Opens the Watchtower screen (see :mod:`meshterm.ui.watchtower_screen`): the alert log
+1
View File
@@ -1 +1,2 @@
# SPDX-License-Identifier: Apache-2.0
"""Presentation layer: Rich theme/widgets and the prompt_toolkit full-screen session."""
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The About MeshTerm pages: the app, the person who wrote it, and how to help it along.
Four read-only pages hung under the main menu's *About MeshTerm* section — the one
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The admin-node picker: choose a remote node you hold (or will enter) credentials for.
Shared by the tools that administer remote nodes over the mesh — TX optimize and the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The Archived contacts list: what the sweep took off the device, and when.
A purge (see :mod:`~meshterm.ui.purge_screen`) removes a contact from the *device* — the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Braille charts: the one way MeshTerm draws a value-over-time row or a meter.
Every timeline in the app — the header's activity pulse, the channel manager's
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The interactive channel manager, rendered in the full-screen session.
This is the user-facing channel-management experience for the ``channels`` tool: a live
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The live chat screen and its launcher.
This is the interactive, full-screen chat experience: a scrolling transcript with an input
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The Device config page: every setting of the companion, and the operations on the box.
Behind the ``config`` tool (:func:`edit_config`), and shaped deliberately like the
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The shared contact list: one sortable, filterable lane layout for every screenful of contacts.
Extracted from the Time Machine's subject picker so the app has exactly one way to draw "a
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The interactive Contacts screen: the device's contacts in the shared sortable contact list.
The Time Machine picker's presentation pointed at the companion's contact table: the same
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""Waiting out a transmit cooldown, visibly and cancellably.
MeshTerm holds itself back between transmissions (see
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The Courier screens: the outbox, queueing flow, and per-message actions.
The interactive face of the ``courier`` tool. One select-list screen carries the whole
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The live mesh dashboard: everything going on around this node, on one screen.
The interactive face of the ``dashboard`` tool. One full-screen, always-repainting view
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
"""The Device info page: everything the companion reports, its pairing PIN concealed.
The page itself is the ``info`` tool's — a live status panel over the full configuration
Loaded 100 of 235 files, more files were not shown because too many files have changed in this diff. Show more