Finishing work on the inline page-image feature (929fa2c):
- Settings: new Browser card with the page-image loading policy
(never/manual/auto/always, upstream image_loading), persisted in NVS
(img_load, default auto); takes effect on the next page load.
- Loader: strict sequential /media fetch with per-image terminal
failure semantics, progress-aware deadline (base window + RTT slack,
refreshed by per-part transfer progress), and a manual "Load images"
action surfaced as a browser-chrome button (no title overlap).
- Mailbox: PROGRESS events carry percent + advertised total (monotonic).
- Decoder: LV_COLOR_16_SWAP byte-swap on-device for lv_draw_img_decoded
buffers (host tests keep mathematical RGB565).
- Render: decoded images blit via lv_draw_img_decoded with a uniform
two-axis 8.8 zoom (no upscale) sized from the placement box; coords
carries the native source dimensions (LVGL SW reads coords size as
src_w/src_h/stride) with the native top-left anchored to center the
scaled image. A width-only zoom made height-constrained boxes overflow
the content edge; a display-size coords made LVGL stride a wide
buffer as narrow, rendering a diagonal offset.
- Progress UI: thin full-width bar under the header (overall page
fraction) plus status line "Image N of M - % - KB".
- Fork pin: microReticulum 921b3aa -> 0487775 (media Resource response
fix + jobs()/outbound() self-re-entrancy guard) at all six sites.
- Tests: x86 real-peer flow gains the media scenario (raw file-response
delivery, 12/12), reference bumped to NomadNet 1.4.3 (e1e8ab8) / RNS
1.5.4 with hash-pinned files; CI installs matching rns/nomadnet and
the flow timeout is raised to 300 s.
- Diagnostics: T:IMG_STATE serial dump (loader entries + decode slots),
test-hook gated and stripped from tdeck-release (audit-verified).
The pyxis-pytest job checks out the microReticulum reference for the
NomadNet x86 client, whose CMake manifest attests the exact commit
(921b3aa, endpoint hot-path read gate). The workflow still pointed at
cd0338e, so the client configure aborted on the attestation check and
the pytest job failed before running tests. The native17 job (submodule)
is unaffected and already green.
The microreticulum-native job installs libbz2-dev without a preceding
apt-get update. When the ubuntu-latest runner's apt index is stale, the
install 404s against the security mirror (pinned libbz2 1.0.8-5.1build0.1
no longer at the indexed URL) and the job fails before any test runs.
This flake is pre-existing — main's own merge commit for PR #92 (520554b)
failed the same way. The sibling pyxis-pytest job already updates before
its install; apply the same here.
Add tools/merge_pyxis_release.py, which assembles the four validated
release assets (bootloader, partition table, OTA selector, application)
into a single 8 MiB image at their fixed flash offsets on an erased
canvas, with per-image read-back and gap checks.
Wire it into release-firmware.yml so every tag build publishes
pyxis-<tag>-merged.bin as a release asset, and document the
provisioning semantics in the README: the merged image is a
first-install image (it erases NVS and LittleFS); data-preserving
updates keep using firmware.bin or the Columba .pyxis package.
Companion to 21b0e96 which deleted BluedroidPlatform.{cpp,h} but
missed staging the three edited files that complete the cleanup:
- platformio.ini: remove the [env:tdeck-bluedroid] env block.
- .github/workflows/build-check.yml: drop tdeck-bluedroid from
the CI matrix.
- lib/ble_interface/BLEPlatform.cpp: drop the
USE_BLUEDROID-gated factory branches.
Same `git add` short-arg trap as the eridanus mishap earlier today
— specifying non-existent paths aborts the add before reaching the
M-file paths. Mental-model fix: stage M-files in a separate `git add`
from the staged-deletes.
Greptile review feedback on PR #21:
ACCEPT:
- test_patch_nimble.py:151 (P1) — replace dead `if False else True`
ternary with a real assertion that "already applied" is absent on
the first run.
- test_patch_nimble.py:247 (P1) — invoke the shim subprocess via
`sys.executable` instead of hardcoded `/usr/bin/python3` so CI's
setup-python interpreter is used consistently.
- workflows/test.yml:50 (P2) — include hash of
deps/microReticulum/platformio.ini in PlatformIO cache key so the
cache invalidates when dependencies change.
MODIFY (narrowed):
- test_ring_buffers.cpp:209 (P2) — keep both `write(data, 0)` and
`write(data, -1)` assertions, but add a comment clarifying that
EncodedRingBuffer::write() takes signed `int length` (not size_t),
so -1 hits the `length <= 0` branch — same as 0. Greptile's
premise (size_t wrap to SIZE_MAX) does not apply to this codebase.
The two assertions lock the contract in case the param is ever
migrated to size_t.
REJECT (silently — no public reply per agent policy):
- test_audio_filters.cpp:237 (P1) — VoiceFilterChain::process()
takes `numSamples = frames * channels` per the documented
contract in audio_filters.h:33-40, and the implementation does
`numFrames = numSamples / channels_` (audio_filters.cpp:63). The
multichannel test correctly passes `(int)samples.size() = 8000`
(4000 frames * 2 channels). No out-of-bounds read occurs.
- lib/lxst_audio/{packet,encoded}_ring_buffer.cpp use malloc/free without
including <cstdlib>. macOS leaks it via header transitivity but Linux
clang is stricter — real portability bug surfaced by the new pytest CI.
- microReticulum native17 tests link against system libbz2 via the fork's
pre:link_bz2.py script. Ubuntu runners need libbz2-dev installed.
Standalone C++ tests of pyxis-unique code (BLE fragmenter/reassembler,
peer manager, GATT op queue, LXST ring buffers, audio filters, HDLC
framing) plus Python tests of the patch_nimble.py build script.
Each C++ test is compiled directly by clang++/g++ with shims in
tests/native/ (Bytes.h, Log.h, Utilities/OS.h) so pyxis sources can build
without microReticulum's full Arduino/MsgPack dep tree. A pytest wrapper
per test compiles, runs, and parses the summary line — the whole suite
is one command: `pytest tests/build_scripts tests/native -v`.
Total: 13 pytest tests, ~72 underlying C++ assertions, 3.4s.
Surfaced an HPF-formula bug in lxst_audio (mirrored upstream in
LXST-kt/native_audio_filters.cpp) — filed as LXST-kt#13 and tracked
in the corresponding test with a TODO link.
CI workflow runs the pyxis pytest suite plus the clean-passing
microReticulum native17 unit tests (94/114 of the existing fork
test/* suites) on push and PR.
grep -q 200 could match 2001 or other superstrings; -qx anchors
to the full line which is correct for curl's %{http_code} output.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Runs both tdeck and tdeck-bluedroid builds on every PR to main.
Uploads firmware binaries as artifacts on the tdeck build for
easy testing by reviewers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generates a styled HTML page from README.md and deploys it to the root
of the GitHub Pages site, fixing the 404 at torlando-tech.github.io/pyxis/.
Includes navigation links to the web flasher, GitHub repo, and releases.
Closes#6
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GitHub release download URLs redirect to release-assets.githubusercontent.com
which doesn't return Access-Control-Allow-Origin headers. The browser blocks
cross-origin fetches from the GitHub Pages flasher, causing "Failed to fetch"
for any versioned release while the latest dev build (same-origin) works fine.
Fix: Deploy versioned firmware binaries to GitHub Pages alongside the dev
build at firmware/releases/{tag}/, so all versions are fetched same-origin.
The CI workflow now downloads existing release assets and deploys them to
Pages with keep_files: true to preserve across deploys.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Lets users choose between the latest dev build and tagged GitHub releases.
The dropdown queries the GitHub Releases API on page load and swaps
firmware fetch paths between Pages-relative and release-asset URLs.
CI now attaches all 4 firmware files to releases (bootloader, partitions,
boot_app0, firmware) so full installs work from any release version.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite release-firmware.yml to build the tdeck (NimBLE) env on pushes to
main (versioned as dev-<sha>) and on v* tags. Remove checked-in firmware
binaries from git tracking — CI now generates and deploys them to Pages.
Release creation is conditional on v* tags only.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split T-Deck firmware from microReticulum examples/lxmf_tdeck/ into its
own repo. microReticulum is consumed as a git submodule dependency pinned
to feat/t-deck. All include paths updated from relative symlinks to bare
includes resolved via library build flags.
Both tdeck (NimBLE) and tdeck-bluedroid environments compile successfully.
Licensed under AGPLv3.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>