Getting started¶
How to pick up CatWandConnect on a new machine, whether you are the maintainer or a new contributor.
Where things stand¶
The dedicated firmware in firmware/ replaces the old ESPHome proof of concept. V1 (issue #1) is complete: v0.1.0, the first stable release, passed the acceptance checklist on a classic ESP32. The ESP32-S3 and ESP32-C3 builds are tested automatically, not yet on real hardware. Planned work carries the future label.
What to read first¶
| Read | For |
|---|---|
CONTEXT.md |
The glossary. Use these words in code, issues and docs. |
docs/adr/ |
Why the big decisions were made: open everything, standalone first, Arduino + PlatformIO, MQTT for Home Assistant, licences, plain web interface. |
| Issue #1 | The V1 spec. Its sub-issues are the tickets, with native "blocked by" links. |
AGENTS.md and docs/agents/ |
How AI agents work with the issue tracker, labels and domain docs. |
What is in the repo and what is not¶
In the repo:
- Logo, banners, photos and screenshots in
media/(seemedia/README.md). - Domain docs, ADRs and agent config.
- Printable parts: Mk3 (current) in
stls/mk3/, Mk2 (previous, electronics outside) instls/mk2/. - The Claude Code project settings that enable the
mattpocock-skillsplugin (.claude/settings.json).
Not in the repo:
- CAD sources. Only STL/3MF exports are committed, and
cads/is empty. To change a part, you need the original CAD project. - The ESPHome PoC. It was removed in
fa58005. Recover it withgit show 3cda6f7:sources/cat-playing-platform.yaml. It is the reference for the PoC motion logic. - Secrets. None are committed, and the new firmware does not need any at build time. Wi-Fi credentials are entered on the device.
- Per-machine setup. Your SSH key, GitHub login, git identity and
.claude/settings.local.jsonmust be recreated on each machine. See below.
Set up a machine¶
1. Tools¶
- Git and the GitHub CLI (
gh). - VS Code with the PlatformIO IDE extension. It provides the toolchain for ESP32, ESP32-S3 and ESP32-C3, plus the native test environment.
- Optional: Claude Code. The
mattpocock-skillsplugin is enabled for this workspace by the committed settings. Accept the install prompt the first time.
2. Clone¶
Contributors can clone normally:
git clone git@github.com:vistorx/CatWandConnect.git
Do not clone into a folder synced by Nextcloud, Dropbox or iCloud. Syncing a .git folder between machines corrupts it. Each machine gets its own clone, and git is the sync.
3. Maintainer only: use the vistorx account on a machine that has another GitHub account¶
On a work machine, the default GitHub account is someone else's. These steps keep vistorx scoped to this repo only.
SSH key, with an alias host so the default github.com is untouched:
ssh-keygen -t ed25519 -C "vistorx" -f ~/.ssh/github_vistorx
# Add ~/.ssh/github_vistorx.pub at https://github.com/settings/keys (logged in as vistorx)
Append this to ~/.ssh/config. Port 443 gets through networks that block port 22.
Host github-vistorx
HostName ssh.github.com
Port 443
User git
IdentityFile ~/.ssh/github_vistorx
IdentitiesOnly yes
AddKeysToAgent yes
UseKeychain yes
Check it with ssh -T github-vistorx, which should greet vistorx.
Clone through the alias and set a repo-local identity:
git clone git@github-vistorx:vistorx/CatWandConnect.git
cd CatWandConnect
git config user.name "vistorx"
git config user.email "vistorx@users.noreply.github.com"
A separate gh login, stored in its own config folder:
GH_CONFIG_DIR=~/.config/gh-vistorx gh auth login --web
Then point this workspace at that folder:
- For Claude Code, create
.claude/settings.local.json. It is git-ignored.
{ "env": { "GH_CONFIG_DIR": "/Users/<you>/.config/gh-vistorx" } }
- For the VS Code terminal, add the following to the
settingsofCatWandConnect.code-workspace, and keep that change uncommitted:
"terminal.integrated.env.osx": { "GH_CONFIG_DIR": "${env:HOME}/.config/gh-vistorx" }
Check it with gh auth status in the workspace terminal, which should show vistorx.
4. Build and test¶
The firmware is one PlatformIO project in firmware/. Run these from that folder, or use the PlatformIO sidebar in VS Code. The VS Code extension installs pio at ~/.platformio/penv/bin/pio.
pio test -e native # Robot core tests on your computer, no board needed
pio run # build for ESP32, ESP32-S3 and ESP32-C3
pio run -e esp32 -t upload -t monitor # flash a board over USB and watch its logs
To work on the Device interface without a robot, run node tools/dev_server.mjs (Node 18+, no install needed) and open http://localhost:8080/. It serves firmware/web/ with a rough simulated robot behind the same API.
The environments are esp32, esp32s3, esp32c3 and native. CI (.github/workflows/ci.yml) runs the tests and the three builds on every push and pull request.
Code layout:
firmware/lib/robot_core/is the Robot core. It is pure C++17 and never includes Arduino headers. It reaches hardware only through theMotorDriver,ClockandStorageinterfaces inports.h.firmware/src/is the Arduino side. It implements those interfaces and wires them to the Robot core.firmware/src/network/gets the robot onto Wi-Fi: Improv provisioning, the fallback hotspot with its setup page, and mDNS.firmware/lib/improv/is the Improv protocol framing, as pure, tested C++.firmware/web/is the Device interface: plain HTML, CSS and JS with no build step. Text lives inweb/lang/*.json. To add a language, copyen.json, translate it, add it toLANGUAGESini18n.js, and runnode tools/check_lang.mjs(CI runs it too).tools/embed_web.pycompresses it into the firmware at build time. The interface talks to the robot only through the Device API.firmware/test/holds the native tests, with in-memory fakes of the interfaces.docs/acceptance-checklist.mdlists what to check on the real robot. Extend it whenever you add behaviour that tests cannot cover.
The firmware uses the min_spiffs partition table: two 1.9 MB app slots for OTA updates, and a 4 MB layout on every chip so 8 MB boards work too. Boards flashed before this layout was adopted need one USB flash to switch; later updates can go over Wi-Fi.
Each build also writes factory.bin, the full flash image (it wipes the settings; the web flasher writes it in two parts that skip them). Publishing a version is described in Releasing; the flasher page is flasher/index.html, and the project website is built from the README and docs/ (see The website and the web flasher). The website is in English and French: each user page page.md has its translation page.fr.md next to it, and python website/check_translations.py (run by CI) checks that none is missing.
If your clone sits in a synced folder, set PLATFORMIO_BUILD_DIR to a folder outside it. Builds write hundreds of megabytes to firmware/.pio/.
Working with an AI agent¶
You can use any coding agent. The project's instructions live in AGENTS.md, the cross-tool convention, and everything it points to is plain Markdown.
| Tool | How it picks up AGENTS.md |
|---|---|
| Claude Code | Automatically. It also loads the mattpocock-skills plugin (/tdd, /triage, …). |
| OpenAI Codex, Cursor, GitHub Copilot (VS Code), Zed, Jules | Automatically. |
| Aider | Through the committed .aider.conf.yml. |
| Gemini CLI | Set "contextFileName": "AGENTS.md" in .gemini/settings.json (local, or in your user settings). |
| Anything else | Tell it to read AGENTS.md first. |
The slash-command skills are specific to Claude Code. Agents without them follow the same conventions by reading docs/agents/, CONTEXT.md and the ADRs.
How work flows¶
- Pick an open ticket that has no open blocker. Tickets labelled
ready-for-agentare fully specified. - Branch from
main, implement test-first where the Robot core is involved, and open a PR that references the ticket. - CI must pass. Behaviour that tests cannot cover goes in the physical acceptance checklist.
- If you settle a new term or decision, update
CONTEXT.mdor add an ADR in the same PR. - If you change an English user page, update its French page (
.fr.md) in the same PR.
Hardware you need to test on the robot: an ESP32, ESP32-S3 or ESP32-C3 board, two MG996R servos, the USB-C power chain from the wiring guide (or a 5 V supply of 3 A or more), and a printed Mk3 (or Mk2) Mechanism.
ESP8266 boards are not supported, and almost certainly never will be. See ADR 0008.
Getting help¶
Questions go to the Discord server; bugs to GitHub issues. See Getting help.