Files
Calendink/Provider/AGENTS.md
2026-03-14 17:27:24 -04:00

4.3 KiB

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

# 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 #includes 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

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.