feat(mesh): Reticulum LoRa hardware gates pass + RNS Resource transfer + image/voice attachments
Phase 0 gates #2/#3 (two-node LXMF-over-LoRa, external Sideband interop) passed
on real hardware (.116's flashed Heltec V3 RNode <-> a phone-flashed RNode running
Sideband) — RNS announce, encrypted DM round-trip, and contact binding all verified
live. Fixed two bugs found in the process: the Reticulum send path wasn't stamping
outbound messages as E2E despite LXMF being unconditionally encrypted, and the
per-message transport pill collapsed Meshcore/Meshtastic into one generic "lora"
color instead of distinguishing the three radio transports.
Built on top of that link: a Columba-style image/file send experience —
compression-quality presets with a real transfer-time estimate (mesh.transport-advice,
now device-throughput-aware), receive-side thumbnail previews + auto-render for
already-local attachments, and async voice messages, all reusing the existing
ContentRef/ContentInline attachment pipeline. The headline addition is genuine RNS
Resource transfer support (daemon-side RNS.Link + RNS.Resource, Rust-side
send_resource/resource_recv plumbing, a new "resource-mesh" transport-advice tier)
so compressed photos up to 2MB now actually transfer over LoRa for Reticulum peers
instead of always falling back to Tor past the small inline-chunk cap.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-06-30 19:57:01 -04:00
|
|
|
#!/usr/bin/env bash
|
2026-07-04 14:44:36 +00:00
|
|
|
# Build the PyInstaller single-binaries for the OTA (plan Phase 1 packaging).
|
|
|
|
|
# Outputs: dist/archy-reticulum-daemon, dist/archy-rnodeconf — drop both next
|
|
|
|
|
# to /usr/local/bin/archipelago.
|
feat(mesh): Reticulum LoRa hardware gates pass + RNS Resource transfer + image/voice attachments
Phase 0 gates #2/#3 (two-node LXMF-over-LoRa, external Sideband interop) passed
on real hardware (.116's flashed Heltec V3 RNode <-> a phone-flashed RNode running
Sideband) — RNS announce, encrypted DM round-trip, and contact binding all verified
live. Fixed two bugs found in the process: the Reticulum send path wasn't stamping
outbound messages as E2E despite LXMF being unconditionally encrypted, and the
per-message transport pill collapsed Meshcore/Meshtastic into one generic "lora"
color instead of distinguishing the three radio transports.
Built on top of that link: a Columba-style image/file send experience —
compression-quality presets with a real transfer-time estimate (mesh.transport-advice,
now device-throughput-aware), receive-side thumbnail previews + auto-render for
already-local attachments, and async voice messages, all reusing the existing
ContentRef/ContentInline attachment pipeline. The headline addition is genuine RNS
Resource transfer support (daemon-side RNS.Link + RNS.Resource, Rust-side
send_resource/resource_recv plumbing, a new "resource-mesh" transport-advice tier)
so compressed photos up to 2MB now actually transfer over LoRa for Reticulum peers
instead of always falling back to Tor past the small inline-chunk cap.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-06-30 19:57:01 -04:00
|
|
|
set -euo pipefail
|
|
|
|
|
cd "$(dirname "${BASH_SOURCE[0]}")"
|
|
|
|
|
|
|
|
|
|
if [ ! -d .venv ]; then
|
|
|
|
|
python3 -m venv .venv
|
|
|
|
|
fi
|
|
|
|
|
.venv/bin/pip install -q -r requirements.txt -r requirements-build.txt
|
|
|
|
|
|
2026-07-04 14:44:36 +00:00
|
|
|
rm -rf build dist archy-reticulum-daemon.spec archy-rnodeconf.spec
|
feat(mesh): Reticulum LoRa hardware gates pass + RNS Resource transfer + image/voice attachments
Phase 0 gates #2/#3 (two-node LXMF-over-LoRa, external Sideband interop) passed
on real hardware (.116's flashed Heltec V3 RNode <-> a phone-flashed RNode running
Sideband) — RNS announce, encrypted DM round-trip, and contact binding all verified
live. Fixed two bugs found in the process: the Reticulum send path wasn't stamping
outbound messages as E2E despite LXMF being unconditionally encrypted, and the
per-message transport pill collapsed Meshcore/Meshtastic into one generic "lora"
color instead of distinguishing the three radio transports.
Built on top of that link: a Columba-style image/file send experience —
compression-quality presets with a real transfer-time estimate (mesh.transport-advice,
now device-throughput-aware), receive-side thumbnail previews + auto-render for
already-local attachments, and async voice messages, all reusing the existing
ContentRef/ContentInline attachment pipeline. The headline addition is genuine RNS
Resource transfer support (daemon-side RNS.Link + RNS.Resource, Rust-side
send_resource/resource_recv plumbing, a new "resource-mesh" transport-advice tier)
so compressed photos up to 2MB now actually transfer over LoRa for Reticulum peers
instead of always falling back to Tor past the small inline-chunk cap.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-06-30 19:57:01 -04:00
|
|
|
|
|
|
|
|
# --collect-submodules: RNS/LXMF load most of their own internals dynamically
|
|
|
|
|
# (interface drivers, transport backends), which PyInstaller's static import
|
|
|
|
|
# analysis can't see from a plain `import RNS`.
|
|
|
|
|
#
|
|
|
|
|
# -d noarchive is NOT optional: RNS.Interfaces/__init__.py builds its
|
|
|
|
|
# `__all__` by glob-ing *.py/*.pyc next to its own `__file__` at import time
|
|
|
|
|
# (`from RNS.Interfaces import *` in Reticulum.py relies on that). PyInstaller
|
|
|
|
|
# normally zips pure-Python modules into an in-binary PYZ archive, so
|
|
|
|
|
# `__file__` doesn't point at a real directory and the glob comes back empty
|
|
|
|
|
# -> `NameError: name 'Interface' is not defined` at RNS.Reticulum() bring-up.
|
|
|
|
|
# noarchive keeps modules as loose .pyc files on disk so the glob still works.
|
|
|
|
|
.venv/bin/pyinstaller --onefile --name archy-reticulum-daemon --clean --noconfirm \
|
|
|
|
|
--collect-submodules RNS \
|
|
|
|
|
--collect-submodules LXMF \
|
|
|
|
|
--collect-data RNS \
|
|
|
|
|
-d noarchive \
|
|
|
|
|
reticulum_daemon.py
|
|
|
|
|
|
|
|
|
|
echo "Built dist/archy-reticulum-daemon ($(du -h dist/archy-reticulum-daemon | cut -f1))"
|
2026-07-04 14:44:36 +00:00
|
|
|
|
|
|
|
|
# archy-rnodeconf: RNS's own official RNode config/diagnostic tool
|
|
|
|
|
# (RNS.Utilities.rnodeconf — reads/sets frequency, bandwidth, spreading
|
|
|
|
|
# factor, coding rate, TX power on an attached RNode; also verifies firmware
|
|
|
|
|
# signatures and can flash/bootstrap a board). Shipped alongside the daemon
|
|
|
|
|
# so every node can inspect and reconfigure its own radio without needing a
|
|
|
|
|
# full RNS/Python dev environment set up by hand — see the checkpoint in
|
|
|
|
|
# docs/RETICULUM-TRANSPORT-PROGRESS.md for the incident (two nodes silently
|
|
|
|
|
# running at different spreading factors, invisible without this tool) that
|
|
|
|
|
# motivated shipping it as a first-class OS tool rather than an ad hoc script.
|
|
|
|
|
RNODECONF_SRC="$(find .venv/lib -maxdepth 5 -path '*/site-packages/RNS/Utilities/rnodeconf.py' -print -quit)"
|
|
|
|
|
if [ -n "$RNODECONF_SRC" ] && [ -f "$RNODECONF_SRC" ]; then
|
|
|
|
|
.venv/bin/pyinstaller --onefile --name archy-rnodeconf --clean --noconfirm \
|
|
|
|
|
--collect-submodules RNS \
|
|
|
|
|
--collect-data RNS \
|
|
|
|
|
-d noarchive \
|
|
|
|
|
"$RNODECONF_SRC"
|
|
|
|
|
echo "Built dist/archy-rnodeconf ($(du -h dist/archy-rnodeconf | cut -f1))"
|
|
|
|
|
else
|
|
|
|
|
echo "WARNING: rnodeconf.py not found at $RNODECONF_SRC (RNS version mismatch?) — skipping archy-rnodeconf build" >&2
|
|
|
|
|
fi
|