No description
- Go 55.6%
- Svelte 23.4%
- TypeScript 10.2%
- NSIS 4.2%
- JavaScript 3%
- Other 3.6%
Describe what the updater actually does (mDNS + USB discovery, Forgejo release fetching with SHA-256 verification, USB-serial and OTA flash paths, device control), list the supported BTClock V4 hardware variants, and explain where this app sits relative to the btclock_v4 firmware repo. Also documents the make targets and the vendored espflasher fork. |
||
|---|---|---|
| .beads | ||
| .claude | ||
| build | ||
| cmd/mdns-debug | ||
| frontend | ||
| internal | ||
| scripts | ||
| third_party/espflasher | ||
| .gitignore | ||
| AGENTS.md | ||
| app.go | ||
| CLAUDE.md | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| Makefile | ||
| README.md | ||
| wails.json | ||
BTClock Updater
A cross-platform desktop app for discovering, updating, and managing BTClock devices on your network and USB.
Built with Wails — Go backend, Svelte 5 + TypeScript frontend, native WebView.
What it does
- Discovers BTClock devices automatically:
- On the LAN via mDNS (
_btclock._tcp, with_http._tcp+model=BTClockas a fallback). - On USB serial, pre-filtering by VID/PID for the chips the BTClock V4 family uses (ESP32-S3 native USB-Serial-JTAG, CP210x, CH340, FT232).
- On the LAN via mDNS (
- Pulls firmware releases from the official BTClock Forgejo
repository at git.btclock.dev/btclock/btclock_v4
and verifies each downloaded asset against its
.sha256sidecar before flashing. - Flashes firmware over two paths:
- USB serial — full image (bootloader, partition table, OTA data,
app, storage) written at the correct offsets in a single connection.
Uses a vendored fork of
tinygo.org/x/espflasher. - OTA over Wi-Fi — app-only update via the device's HTTP endpoint with Basic-Auth and server-side SHA-256 verification.
- USB serial — full image (bootloader, partition table, OTA data,
app, storage) written at the correct offsets in a single connection.
Uses a vendored fork of
- Controls running devices: identify (blink LEDs), reset, open the on-device web UI.
Hardware support
| Variant ID | Display | Chip | Flash |
|---|---|---|---|
rev_a |
BTClock V4 (Rev A, 2.13″) | ESP32-S3 | 4 MB |
rev_a_29 |
BTClock V4 (Rev A, 2.9″) | ESP32-S3 | 4 MB |
rev_b |
BTClock V4 (Rev B) | ESP32-S3 | 8 MB |
v8 |
BTClock V8 | ESP32-S3 | 16 MB |
Flash layouts are defined in internal/manifest/variants/.
Where this fits in the BTClock ecosystem
- btclock_v4 — the
firmware itself. Tagged releases publish per-variant
.binartifacts with.sha256sidecars; this app consumes them. - BTClock Updater (this repo) — desktop tool that finds your device
and writes that firmware to it. The end-user alternative to running
esptool.pyor curling the OTA endpoint by hand.
Development
wails dev # Vite HMR for the Svelte frontend + live-bound Go methods.
# Devtools server runs at http://localhost:34115
Building
wails build # Build for the current host platform.
make mac # Universal unsigned .app
make mac-signed # Universal signed + notarized .app
make mac-dmg # …plus a .dmg
# Signed/notarized builds expect:
# SIGN_IDENTITY="Developer ID Application: ... (TEAMID)"
# NOTARY_PROFILE=<keychain profile from `xcrun notarytool store-credentials`>
Windows installer and icon assets live under build/windows/;
regenerate icon.ico from build/appicon.png with make icons
(requires ImageMagick).
Project layout
app.go Wails-bound App: discovery, jobs, flashing
internal/discovery/mdns/ LAN discovery (dns-sd on macOS, zeroconf elsewhere)
internal/discovery/serial/ USB serial port enumeration + BTClock VID/PID tagging
internal/flash/serial/ USB flashing via espflasher
internal/flash/ota/ OTA upload over HTTP
internal/devicectl/ Identify / reset / web-UI helpers
internal/forgejo/ Forgejo Releases client (download + sha256 verify)
internal/manifest/ Per-variant flash layouts (embedded JSON)
frontend/ Svelte 5 + TypeScript UI
third_party/espflasher/ Vendored fork — see note below
Vendored espflasher
third_party/espflasher is a temporary local
fork of tinygo.org/x/espflasher carrying a one-line patch
(upstream PR #42)
that fixes a hardcoded 4 MB SPI parameter so writes past 4 MB succeed on
8 MB and 16 MB ESP32-S3 chips. The replace directive in go.mod will be
dropped once a patched upstream release is tagged.