feat(mesh): !archy command — node status over the mesh, no AI

`!ai` sends the question to a language model. `!archy` never does: it reads
the same status caches the /bitcoin-status and /electrs-status endpoints
serve, so answers are deterministic, cost no tokens, and stay available when
the assistant is switched off.

Sub-commands: status (default), btc, electrs, version; anything else returns
a usage hint. Replies are single-frame terse to respect airtime.

Reuses the assistant's trust gate (is_sender_allowed) and reply routing
unchanged — blocked, allowlist, trusted_only and federation-Trusted all
behave identically. The one deliberate asymmetry is that !archy does not
require assistant_enabled, since it never calls a model.

Wired into both entry paths: plain radio text (decode.rs) and typed 1:1
chat (dispatch.rs). A command hooked into only one of them would work from
a phone but not the UI, or vice versa.

Adds docs/COMMANDS.md — the user-facing surface for mesh, voice and HTTP,
which had no reference until now.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-07-09 12:57:14 +01:00
co-authored by Claude Opus 4.8
parent be50c886bb
commit e56c5af3ba
7 changed files with 414 additions and 23 deletions
+7
View File
@@ -108,6 +108,13 @@ run the same gated `run_assist`. This means **any meshcore client** (even a bare
Meshtastic-style sender) can ask, while typed `AssistQuery` is the rich path our
own UI uses. Trigger + enable are config.
A sibling command, **`!archy`**, answers node-status questions from the local
status caches with no model in the loop (`mesh/listener/node_cmd.rs`). It reuses
this design's trust gate (`is_sender_allowed`) and reply routing verbatim, but
deliberately does *not* require `assistant_enabled` — turning the LLM off should
not take node status with it. See [COMMANDS.md](COMMANDS.md) for the full
user-facing command surface.
### 1.6 UI events (`types.rs`)
```rust
AssistQueryReceived { from_contact_id: u32, prompt: String },