Skip to content

variants/linux: meshcorectl, a dependency-free client for the console - #11

Open
mmmorks wants to merge 1 commit into
pr/05-pty-consolefrom
pr/05b-meshcorectl
Open

variants/linux: meshcorectl, a dependency-free client for the console#11
mmmorks wants to merge 1 commit into
pr/05-pty-consolefrom
pr/05b-meshcorectl

Conversation

@mmmorks

@mmmorks mmmorks commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Summary

A client for the PTY console, for the cases meshcore-cli -r does not cover. Its repeater mode is fine interactively, but in one-shot form it exits 0 whatever the daemon answered, waits a fixed 0.3 s and reads once, and cannot take commands from stdin, so a deploy script cannot tell set freq 868 from ERR: bad value or from a daemon that never read the line. It is also a pipx install that pulls in the BLE stack, on a host that may be a Pi Zero with nothing but python3.

meshcorectl is one file on the standard library:

  • REPL with readline editing, history in ~/.meshcorectl_history, and Tab completion of the real command set (tables checked against the dispatch literals in CommonCLI.cpp and MyMesh.cpp; get and set have separate key pools).
  • One-shot (meshcorectl set name foo) and piped (printf 'ver\nneighbors\n' | meshcorectl) forms.
  • Exit 0 only if every command was actually run by the daemon. The echo is the proof: the daemon echoes a command byte by byte as it consumes it and only then replies, so reboot counts as run, and a later command in the same script that finds the console hung up fails with a message saying why.
  • Finds the console the way the daemon publishes it (/run/meshcored/console, then $XDG_RUNTIME_DIR/meshcore/console, then /tmp/meshcore-<uid>/console); -s PATH or MESHCORED_CONSOLE overrides.

Its docstring records the firmware behaviours it cannot fix (clock sync needs a sender timestamp the console passes as 0; region load is multi-line).

What changed

  • variants/linux/meshcorectl: the client.
  • README: installed alongside meshcored in §1; §5 shows it next to meshcore-cli; ## The control CLI gains the three ways to drive it and the exit-code contract.

How it was tested

Exercised against a stand-in console (a Python PTY driven like the firmware loop) on macOS and in the arm64 container: one-shot, piped, --help, a missing path, a non-console path, a command with no reply text, and a piped script that continues past reboot (exit 1 with the reason). Not yet run against a real node.

Dependencies

Stacked on the PTY console hardening PR (pr/05-pty-console). Review the last commit only. Optional: the console works with meshcore-cli without this.

Shared code touched

None.

meshcore-cli's repeater mode covers interactive use of the console well.
What it does not cover is scripting: its one-shot form exits 0 whatever
the daemon answered, waits a fixed 0.3 s and reads once, and has no way
to take commands from stdin -- so a deploy script cannot tell "set freq"
from "ERR: bad value" or from a daemon that never read the line. It is
also a pipx install that pulls in the BLE stack, on a host that may be a
Pi Zero with nothing but python3.

meshcorectl is one file on the Python standard library: a readline REPL
with history and Tab completion of the real command set (the tables are
checked against the dispatch literals in CommonCLI.cpp and MyMesh.cpp), a
one-shot form, and a piped form, exiting 0 only if every command was
actually run by the daemon. The echo is the proof: the daemon echoes a
command byte by byte as it consumes it and only then replies, so text
that starts with the echo is a reply and anything else is the reason
nothing ran. That makes `reboot` count as run, and a later command in the
same script, finding the console hung up, fail with a message that says
why. It resolves the console the same way the daemon publishes it
(/run/meshcored/console, then $XDG_RUNTIME_DIR/meshcore/console, then
/tmp/meshcore-<uid>/console); -s PATH or MESHCORED_CONSOLE overrides.

Exercised against a stand-in console (a Python PTY driven like the
firmware loop) on macOS and Linux: one-shot, piped, --help, a missing
path, a non-console path, a command with no reply text, and a piped
script that continues past reboot.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXSCjgNEbJfHwLjD2WSHW4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant