# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. Claude Code-specific notes for this project. For architecture, hard rules, and full command reference — see [AGENTS.md](AGENTS.md), and read it before starting work. ## Quick orientation DeskLock = firmware for a Waveshare ESP32-P4 round-display device (`firmware/`, ESP-IDF/C/LVGL) plus a voice gateway container (`gateway/`, Python/FastAPI, port 8600) that bridges device audio to the Tatlock butler API. The device↔gateway WebSocket protocol lives in `docs/architecture.md` and must stay in sync with both implementations. ## Commands ```bash # Firmware (requires `source ~/esp-idf/export.sh` first; IDF ≥ 5.4) cd firmware && idf.py build idf.py -p /dev/ttyACM0 flash monitor # Gateway cd gateway && make setup # once make run # dev server :8600 make test # pytest; single test: .venv/bin/pytest tests/test_health.py -k healthz make lint typecheck ``` ## Gotchas - ESP-IDF v5.5 lives at `~/esp-idf` (`source ~/esp-idf/export.sh`). Flash via `sg dialout -c …` (see AGENTS.md) — the login session predates dialout membership. - **PSRAM 200 MHz requires `CONFIG_IDF_EXPERIMENTAL_FEATURES=y`** — without it the option silently degrades to 20 MHz and the DSI display underruns into a watchdog loop. Details in AGENTS.md. - **Wi-Fi = esp_hosted 2.x on BOTH chips** (host manifest + C6 slave, auto-OTA'd from `main/c6_slave.bin`). 1.x on IDF 5.5 gives working control RPC but a dead data path (the great July 14th debugging night). Boot-loop assert on `xTaskCreateStaticPinnedToCore` = internal-RAM famine. Details in AGENTS.md. - Gateway speech deps are optional extras; `make setup` alone runs the app and tests without GPU/ML packages. `make setup` uses `python3.12` (system python3 is 3.8). - Tatlock replies open with a `` block — always strip via `tatlock.strip_reasoning()` before TTS or display. - Low power is a prime user requirement: see "Power management" in docs/architecture.md before touching the face/render loop.