# AGENTS.md

Calendink Provider — ESP32-S3 firmware + Svelte 5 web dashboard.
Uses **ESP-IDF** (not Arduino). Serves UI from LittleFS flash partitions over Ethernet/WiFi.

---

## Build Commands

```powershell
# Backend (from project root)
idf.py build
idf.py flash monitor

# Frontend (from frontend/)
npm run dev            # Dev server — calls real ESP32 API (set VITE_API_BASE in .env.development)
npm run build          # Production build → dist/index.html
npm run build:esp32    # Build + gzip → dist/index.html.gz
npm run ota:deploy     # OTA deploy frontend to device
### Logging on Ethernet
When the device is connected via Ethernet, logs are broadcast over UDP. Run `ncat -ul 514` on your PC to view the live `ESP_LOG` output.
*(If `ncat` throws a `WSAEMSGSIZE` error on Windows, use this Python command instead:)*
```powershell
python -c "import socket; s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM); s.bind(('', 514)); [print(m[0].decode(errors='ignore'), end='') for m in iter(lambda:s.recvfrom(4096), None)]"
```

There are no automated tests. Verify by building and inspecting on-device.

---

## Project Layout

```
main/                   C++ firmware (Unity Build — one translation unit)
main/api/<domain>/      HTTP endpoint files, one per verb
main/http_server.cpp    Server setup, static file serving, scratch buffer pool
main/connect.cpp        Ethernet + WiFi management
frontend/src/           Svelte 5 components + api.js
frontend/src/app.css    TailwindCSS v4 @theme design tokens
tdd/                    Technical Design Documents — read before major changes
.agents/rules/          Coding guidelines
```

---

## Backend Rules (C++ / ESP-IDF)

- **Unity Build**: `main.cpp` `#include`s all `.cpp` files. Do NOT add files to `CMakeLists.txt`.
- **C-style only**: no classes, no `std::`, no RAII, no exceptions. `template`, `auto`, `constexpr` are fine.
- **`internal`** (= `static`) on all file-scoped symbols — defined in `main/types.hpp`.
- **Logging**: use `ESP_LOGI` / `ESP_LOGW` / `ESP_LOGE` only — never `printf()`.
  - Because of Unity Build, tag variables must have unique names per file: `kTagHttpServer`, `kTagMain`, etc. — never use a shared `TAG`.
- **Seed data**: `seed_users()` / `seed_tasks()` must be inside `#ifndef NDEBUG` guards.
- **API handler pattern**: set CORS header + response type → parse request → call store function → build cJSON response → `free()` strings, `cJSON_Delete()` objects.
- **Data is in-RAM only** (`g_Users[8]`, `g_Tasks[32]`). This is intentional — persistence is a future milestone. Don't add it without a TDD.

---

## Frontend Rules (Svelte 5 + TailwindCSS v4)

- **Tailwind only** — no `<style>` blocks in components. Design tokens are in `frontend/src/app.css` (`@theme`).
- **Svelte 5 runes only** — `$state`, `$derived`, `$effect`, `$props`, `$bindable`. No `export let`, `onMount`, `onDestroy`, `writable`, or `.subscribe()`.
- **`$state()`** for values the template reads. **Plain `let`** for script-only handles/flags the template never reads.
- **`$effect()` with no reactive deps** runs once on mount — add a comment saying so.
- All API calls through `lib/api.js` via `trackedFetch()` — never raw `fetch()`.
- Shared utilities (formatters, helpers) in `lib/utils.js`. Never duplicate functions across components.

---

## Technical Design Documents

Read the relevant TDD before any major architectural change:

| TDD | Read when |
|---|---|
| `tdd/backend_architecture.md` | Changing server setup, adding API groups |
| `tdd/frontend_technology_choices.md` | Changing build tools or dependencies |
| `tdd/todo_list.md` | Changing task/user data model or API contracts |
| `tdd/firmware_ota.md` | Touching OTA partition logic |
| `tdd/frontend_ota.md` | Touching frontend OTA upload or versioning |
| `tdd/concurrent_requests.md` | Changing HTTP server socket/connection config |
| `tdd/lvgl_image_generation.md` | Touching LVGL headless display or image gen |
| `tdd/device_screens.md` | Changing device registration, MAC routing, or XML layout logic |

---

## Working with the User

- After finishing a task: explain what changed, what you recommend next, and wait for approval.
- Never make changes beyond the agreed scope without asking first.
- Write a TDD (see `.agents/rules/how-to-write-tdd.md`) before major architectural changes.
- **Keep `AGENTS.md` and `GEMINI.md` up to date.** If a task changes the architecture, adds new rules, introduces new build commands, or modifies the project layout — update both files before closing the task.
