20 Commits
Author SHA1 Message Date
Kaj SchittecatandClaude Opus 5 a80a48988e touch: report a build from the device, and a QR that files a bug
Settings, About gains "Report this build": works or a problem, five tick
boxes for what you actually exercised, how long you have run it, an optional
line. It posts to the report service and lands on wadamesh.com/beta, which is
what the next promote is decided on. Ticking matters: "it works" from somebody
who watched it boot and "it works" from somebody who messaged on it all week
are not the same claim, and a board only goes green on two of the second kind.

"Report a bug" draws a QR for a prefilled GitHub issue form. The issue is filed
from the reporter's phone under their own account, so no write token has to
exist in a public firmware image and the reporter gets the replies.

"Count this device" is off by default. It lets the update check say which board
and version it is running, so a board with no reports can be told apart from a
board nobody owns. Those need opposite responses and nothing could tell them
apart before.

Mechanics: the POST rides the existing core-0 tile/update worker and its
WiFiClient/HTTPClient, like the version check, because a second pair on that
~8 KB stack overflows it. The device id is a salted SHA-256 of the public key
truncated to 64 bits, so a second report replaces the first without saying who
sent it. Sending is two taps and the second lists every field that leaves.
Prefs v64 appends report_ping + report_done_n at the tail, which the schema's
trailing static_assert now checks.

Also here: scripts/build/matrix-check.sh prints what testers reported for a tag,
and release.sh runs it before a --promote. It never blocks; a board nobody owns
can never go green. With no reports at all it now says so rather than reporting
a clean bill of health, which is the habit this is meant to replace.

Built on all eleven S3 envs and the T-Display P4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 11:29:20 +02:00
Kaj SchittecatandClaude Opus 5 5d5f7bc638 release: beta_84 notes, and let a promotion skip boards it predates
A board added mid-cycle (the T-Deck Max) has no images in an older tag, so
promoting that tag copied a file that does not exist and, with set -e, took
the whole promotion down. It is skipped with a note now, and the flasher
manifest generator leaves out any board with no image in the channel it is
writing, rather than handing the flasher a 404.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 14:39:22 +02:00
Kaj SchittecatandClaude Opus 5 9c47a9e50d touch: fixes on the merged PRs, and ship the T-Deck Max
Review of #531 turned up four things that had to be fixed before release:

- An unusable region name no longer discards the radio settings. The save
  returned early, so frequency, bandwidth, SF, CR and TX power were thrown
  away, and the rule rejects names with capitals or a "$private" scope, so
  anyone carrying an older region could not change their radio at all. On the
  pager that path is the silent blur save, so it failed with nothing on screen.
  Now only the region is skipped, and it says so.
- Restored useChainedFont() on the telemetry Show button: without the fallback
  chain that label is boxes in Russian, Ukrainian, Bulgarian, Serbian, Greek.
- Region scanning installs unknown repeaters as transient contacts so their
  encrypted replies can be matched. They were never removed, so each scan left
  up to 16 nameless entries in the contact table (and in Contacts). They are
  dropped when the scan ends or the page closes.
- One radio request per scan tick. The loop ran through all 16 repeaters in a
  single 200 ms tick, which is that many key derivations back to back.

The V4-R8 also did not build (its src/ files see a vendored lv_conf.h, so the
new text-size fonts were missing) and then did not fit at 101.3%. It builds at
85.6% now: the board no longer carries the compiled-in translations it
inherited from the V4, which it never needed, since with 8 MB of PSRAM its
store works like any other 8 MB board.

T-Deck Max (#545) joins the release matrix: build list, flasher manifest,
DEVICES.md and the site's board list. Board names in the flasher lost their
em dashes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 14:04:24 +02:00
Kaj SchittecatandClaude Opus 5 20d79edae9 release: publish the LilyGo T-Deck Pro as experimental
Adds LilyGo_TDeck_Pro_companion_radio_touch to release.sh (as
wadamesh-tdeck-pro), a flasher manifest labelled "(experimental)", and a
website card following the V4-R8 pattern: experimental in the heading,
"Partially supported", beta only.

The card says plainly what is known: contributed through #469, all the main
hardware works, but it has been tested on a single v1.1 unit, v1.0 units are
the least proven, and the e-paper display redraws rather than updating
instantly.

The site is not deployed with this commit: the card's install button points at
manifest-tdeck-pro.json, which only exists once a beta containing the board is
published.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 12:20:09 +02:00
Kaj SchittecatandClaude Opus 5 92b2ed12c9 Ship the Wio Tracker L2: release plumbing, not just the build
The PR added the board and its env, which makes it build. It does not make it
ship. Three lists decide that and none of them knew about it: release.sh ENVS
(what gets built and named into a release), gen-flasher-meta.py BOARDS (which
manifests the web flasher gets) and the flasher page itself, which lists boards
by hand.

Without these the board compiles cleanly forever and never appears in a release
or on the flasher, which looks like nothing is wrong.

Named wadamesh-wio-tracker-l2, its own Seeed Studio section on the flasher,
marked beta-channel-only like the Attaky was on arrival, since stable is still
beta_65 and this board has never been in a stable build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 23:59:06 +02:00
Kaj SchittecatandClaude Opus 5 e6678b8fe7 release: keep the firmware push away from the app store
The Lua app and language store shares a document root with the firmware but is
published by deploy-apps.sh from deploy/apps/, which is the canonical copy.
release.sh pulls the published tree into out/firmware/ before building, so
apps/ arrives as a local mirror, and the push at the end sends that mirror
back.

Today that reverted the store to sdktest 1.2 and language v15 and removed two
apps, minutes after deploy-apps.sh had published sdktest 1.6, language v18,
airtime 1.4 and gpscompass. It is also the same stale directory that
gen-lua-builtin.py was reading until yesterday, so this mirror has now caused
two separate failures and holds nothing anyone wants.

Excluded in both directions. The firmware release never publishes the store.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 10:39:43 +02:00
Kaj SchittecatandClaude Opus 5 7bc55ef205 release: firmware-data gate broke on its own pipefail (grep -q SIGPIPEs strings)
The script runs under 'set -o pipefail'. grep -q exits at the first match, which
SIGPIPEs the strings feeding it, so the pipeline reported failure and the gate
declared every image untagged — on its first real run, against images that
carried the tag correctly. Count instead of short-circuiting.

The build-date change in the previous commit was precautionary (it matches the
convention the meshcomod release flow already uses); I have no evidence the
spaces were actually breaking the flags, and should not have called it the fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 13:12:31 +02:00
Kaj SchittecatandClaude Opus 5 46960f0cd2 release: build date must not contain spaces (it broke the whole flag string)
PLATFORMIO_BUILD_FLAGS is whitespace-split, so '10 Aug 2026' tore the string
apart and every -D after it was dropped — including FIRMWARE_RELEASE_TAG, which
is precisely the untagged-build failure the new gate exists to catch. The gate
caught it on the first real run and stopped beta_61 before anything published.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 13:04:46 +02:00
Kaj SchittecatandClaude Opus 5 335a64c118 touch: core-v1.17.1 (beta_60 boot loop + unreachable contacts) + release firmware-data gate
Core (core-v1.17.1, meshcomod 5406093): 1.17 reserved MAX_ANON_CONTACTS slots
at the head of contacts[], which broke two things in beta_60 —

- resetContacts() claimed those slots while the lazily-allocated PSRAM table was
  still NULL, so the new bootstrapRTCfromContacts() NULL-deref'd at boot on any
  device whose contact store loaded nothing: fresh install, erase-flash, or SD
  not mounted yet (#249). Boards with saved contacts booted fine, which is how
  it passed bench testing.
- getContactByIdx() stayed raw while getNumContacts() excludes the reserved
  slots, so every pairing of the two — contact list, action sheets, phone-app
  sync, getContactForSave — read empty slots and could not reach the newest 8
  real contacts. A just-added contact was invisible and its action-sheet
  operations resolved to a blank slot (#252).

Fork side:
- loadContacts() skips blank records, clearing the placeholder contacts beta_60
  wrote into the contacts file (the next save drops them permanently).
- Chat threads follow a peer's rename. The thread is matched by key but its name
  was never updated, while inbound messages are filed by sender name — so the
  first message after a rename created a duplicate thread (#252).
- release.sh derives FIRMWARE_VERSION / build date / core version from the tag
  and the pinned core, keeps the in-tree dev default in step, and ABORTS the
  release if any staged image does not embed its own tag. beta_60 shipped
  reporting v1.16.0-touch because that value was hand-maintained.

All 8 S3 envs build green on core-v1.17.1.

Reported-by: Pierre747, rustinmyeye, myshoeisonfire

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 08:20:00 +02:00
Kaj SchittecatandClaude Opus 4.8 99423e5bf8 touch: beta_47 — Discover app (find/list/map nearby nodes + wardriving), Attaky release wiring, P4 LCD
- New Discover app: active NODE_DISCOVER sweep -> signal-ranked nearby list, tap-to-add-contact, GPS wardriving log (SD CSV) + signal-coloured coverage overlay on the map. Board-agnostic.
- T-Display P4 TFT-LCD (HI8561) variant support (WADA_P4_LCD build; AMOLED bin untouched).
- Wire the Attaky Core board (#158, @attakygit) into the release matrix + web flasher.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 17:45:05 +02:00
Kaj SchittecatandClaude Opus 4.8 ae02fb6238 release: beta_45 infra — T-LoRa Pager + T-Display P4 in the flasher matrix
- release.sh: add both T-LoRa Pager envs (LR1121 + SX1262) to the PIO build set.
- gen-flasher-meta.py: add pager (×2) + T-Display P4 manifests; P4 carries
  chipFamily ESP32-P4 (per-board now, not hardcoded S3).
- site: LilyGo T-LoRa Pager board card (both radio variants) with the
  partially-supported badge; the P4 card already landed last cut.
- release-notes/beta_45.txt (leads with @codemonkeybr's pager port).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 20:32:31 +02:00
Kaj SchittecatandClaude Opus 4.8 687eb3865c touch: add Heltec WiFi LoRa 32 V4-R8 board (8 MB octal PSRAM + Expansion Kit V2 SD)
The V4-R8 uses an ESP32-S3R8 (8 MB OCTAL PSRAM) which claims GPIO33-37, so
Heltec moved every control signal off them and the Expansion Kit V2 rebuilt the
display/touch/SD block onto a hardware-SPI bus:
  Vext 36->40 (active-LOW) . GPS_EN 34->42 . LED 35->46 . ADC_Ctrl removed
  TFT (LovyanGFX HW-SPI): MOSI=15 SCK=16 MISO=45 CS=47 DC=48 RST=21 BL=44
  touch (CHSC6x, shares board I2C 17/18) . micro-SD (shared TFT SPI, CS=3)

The build defines HELTEC_LORA_V4_TFT too, so it reuses all the V4 touch-UI code;
HELTEC_LORA_V4_R8 gates only the deltas. 8 MB enables the on-device web browser
(CAP_WEB_BROWSER) and the SD card (CAP_SD). Also wires the board into the release
+ web-flasher pipeline (release.sh, gen-flasher-meta.py, the flasher picker).

UNTESTED — no V4-R8 hardware yet. Pin sources: Meshtastic heltec_v4_r8 variant,
Heltec V4-R8 pinmap, and the Expansion_board_V2.03 schematic. All three touch
envs build clean; V4/T-Deck unregressed. On-device TODO: CHSC6x shared-Wire on
17/18, SD_CS=3, and the V2 PAM8904 buzzer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 11:27:40 +02:00
Kaj SchittecatandClaude Fable 5 cb08116eae flasher/site: ThinkNode M9 + RAK WisMesh Tap V2 web-flash support
Both new S3 boards are installable from the browser now: release.sh
builds and ships their bins per channel, gen-flasher-meta emits their
esp-web-tools manifests, and the site gets install cards for both.
The cards are pinned to the beta feed (with a note) until the first
stable promote that includes their bins; the wmSetChannel comment says
how to unpin then. beta_38's beta feed and GitHub release carry the
new bins retroactively.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 13:55:35 +02:00
Kaj SchittecatandClaude Opus 4.8 03e50b0609 touch: beta_21 — first stable build + test channel, MQTT bridge, contacts & signal-probe fixes
New: stable/test update channels with an opt-in "Get test builds (beta)" toggle on
OTA devices (switches both the update check and what you install); experimental
opt-in MQTT bridge (consent-gated, payload encryption, direct messages off by
default); Portugal (Narrow) region preset (#74); saved-contacts counter in the
Contacts overflow menu (#72).

Fixed: the signal probe is now strictly zero-hop so a repeater can't re-flood it;
the contact list sorts before capping so the most relevant contacts show, with a
"+N more — search to narrow" footer (#73); the blocked-users list opened from
Contacts shows the two-line title bar with a back button; the Contacts overflow
popup fits the screen again.

Also lands the two-channel release tooling (scripts/release.sh stable/beta modes +
gen-flasher-meta channel arg), the docs site, and the MQTT reference decryptor.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 17:34:11 +02:00
Kaj SchittecatandClaude Opus 4.8 c16b5230a6 release: auto-refresh + push the Mesh America catalog each beta
release.sh now regenerates deploy/meshamerica-catalog.json for the tag and, when
run on main, commits + pushes that one file so apps.meshamerica.com (the flasher
Cascadia Mesh uses) always points at the newest immutable bins instead of going
stale on the previous beta. Idempotent (no-op when already current); non-fatal if
the push fails; also mirrors the catalog into the VPS publish tree.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 22:27:28 +02:00
Kaj SchittecatandClaude Opus 4.8 a405513d84 flasher: show current release version + notes (pipeline-driven)
The esp-web-tools manifest carried a frozen version:beta_1 while the rolling
/latest/ bins moved on, so the web flasher always said beta_1. Fix:
- scripts/build/gen-flasher-meta.py emits version.json (tag + notes) + per-release
  manifests (version=tag) into /latest/; release.sh + the CI workflow run it, so
  the metadata rolls with every release.
- the site points the install buttons at the VPS manifests and renders a live
  'What's new in <tag>' block from version.json.
- drop the frozen static site manifests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 16:08:10 +02:00
Kaj SchittecatandClaude Opus 4.8 c4798dceab site: guided landing at wadamesh.com — Standalone vs bmorcelli's Launcher
deploy/site/: a visual install journey served at the apex. Hero + an animated
mesh backdrop, then a two-path chooser:
  - Standalone  -> embedded esp-web-tools flasher (board picker, 3 steps)
  - With Launcher -> step-by-step + app-image downloads (/latest/*.bin)
apex vhost switched from 301->flasher to serving the landing; release.sh now also
rolls the app-only bins into /latest/ for the Launcher path. Deployed + verified
live through Cloudflare (wadamesh.com 200).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Kaj Schittecat <kaj@schittecat.com>
2026-06-13 10:50:45 +02:00
Kaj SchittecatandClaude Opus 4.8 27303ad948 deploy: web flasher (esp-web-tools) + apex redirect + rolling /latest/
- deploy/flasher/: browser Web Serial installer (board picker for V4 + T-Deck),
  manifests pointing at firmware.wadamesh.com/latest/*-merged.bin
- deploy/nginx/firmware: serve /latest/ + Access-Control-Allow-Origin so the
  flasher fetches bins cross-origin
- deploy/nginx/flasher: flasher.wadamesh.com vhost + wadamesh.com/www 301->flasher
- release.sh: refresh the rolling /latest/ merged bins each publish

Deployed + verified live through Cloudflare. VPS IP kept out of the repo
(Cloudflare fronts the origin).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Kaj Schittecat <kaj@schittecat.com>
2026-06-13 10:41:00 +02:00
Kaj SchittecatandClaude Opus 4.8 95b0233832 fix: release.sh runs on macOS bash 3.2 (drop associative array)
declare -A needs bash 4+; macOS ships bash 3.2. Replaced the env->binname map
with a portable 'env:name' string + parameter-expansion split. Verified
end-to-end: built beta_1 for both boards, rsynced to the firmware VPS, origin
serves the listing + bins.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Kaj Schittecat <kaj@schittecat.com>
2026-06-13 10:02:26 +02:00
Kaj SchittecatandClaude Opus 4.8 eb07184c3e deploy: VPS + Cloudflare bundle (nginx vhosts, release script, setup guide)
The wadamesh.com distribution stack, ready to drop onto a new VPS behind
Cloudflare:
- deploy/nginx/tiles.wadamesh.com.conf — OSM tile proxy (HTTP origin, double-quoted
  location regex, resolver + variable proxy_pass, OSM UA, 14d disk cache)
- deploy/nginx/firmware.wadamesh.com.conf — bins + the beta_<N> update-check listing
- scripts/release.sh — build both boards tagged, refresh the listing, rsync to the VPS
- deploy/README.md — VPS + Cloudflare DNS/SSL/cache setup, publish flow

VPS target supplied via $WADAMESH_VPS at publish time — no IP/SSH in the repo
(Cloudflare fronts the origin). Web flasher + OTA re-enable are the remaining
pre-launch pieces (noted in deploy/README.md).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Kaj Schittecat <kaj@schittecat.com>
2026-06-13 09:04:17 +02:00