A workshop for handheld and embedded device projects β a tinkerer's playground held to production discipline.
zenyatta is a monorepo of small, self-contained projects for handheld and
embedded hardware: ESP32 firmware, atomic Linux images for Linux-capable
handhelds, and whatever else the bench turns up next. Each subproject stands on
its own β its own toolchain, its own build, its own README β but they all
answer to one set of rules in CLAUDE.md.
The throughline is formalized, reproducible craft: hobby scope, not hobby rigor. Declarative builds over hand-rolled steps, one operator interface per project, no secrets in the tree, and a clean working directory. PlatformIO for firmware and BlueBuild/bootc for images are both chosen for the same reason β they make a build a description you can read, not a ritual you memorize.
Two shapes recur. A new project should fit one of them, or declare in its
README why it doesn't.
| Archetype | Stack | Deliverable | Example |
|---|---|---|---|
| Firmware | PlatformIO + Arduino / ESP-IDF, ESP32 family | Flashable firmware | WOPR/ |
| Atomic image | BlueBuild + bootc / image-builder | Flashable .raw / OCI image |
cardputer-zero/ |
| Path | What it is | Target hardware | Status |
|---|---|---|---|
WOPR/ |
Scrolling LED-matrix display β clock + live stock tickers over Wi-Fi | ESP32-C3 + MAX72xx 8Γ8 matrices | Working firmware |
cardputer-zero/ |
Immutable Fedora bootc handheld image with a security toolset |
M5Stack CardputerZero (Pi CM0, aarch64) | Implementation plan |
| m5stackchan (planned) | Animated desktop companion (stack-chan) | ESP32-S3 | Idea |
- Create a top-level directory named for the project.
- Pick an archetype and scaffold its standard toolchain β a PlatformIO project or a BlueBuild recipe.
- Give it a
README.md(what it is, the hardware, how to build and flash) and ajustfileexposing every operator action. - Keep secrets out of the tree: gitignore them and commit a
.exampletemplate (seeWOPR/include/credentials.h.example). - Follow
CLAUDE.mdβ it governs every subproject in this repo.
- One operator interface. Everything a human runs is a
justtarget β never a bare multi-line snippet pasted into docs. - No secrets, ever. Credentials live in gitignored files (
.env,include/credentials.h) with committed.exampletemplates. Public config (a ticker list, a package list) is configuration, not a secret, and can be tracked. - Declarative beats imperative. A build should be a file you can read top to
bottom β a
platformio.ini, arecipe.ymlβ not steps you have to remember. - Self-contained subprojects. No cross-subproject coupling; each builds from its own directory with its own toolchain.
- Hardware lives behind a seam. Pin maps, board configs, and chipset constants live in one place per project so that retargeting a board is a config change, not a rewrite.
- Leave it better. Fix what you find; keep the working tree clean β research
clones and scratch go to
/tmp.
The full rules β security, error handling, docs, specs, supply-chain hygiene,
commits, and per-archetype conventions β live in CLAUDE.md.