3.9 KiB
3.9 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
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.cppfiles. Do NOT add files toCMakeLists.txt. - C-style only: no classes, no
std::, no RAII, no exceptions.template,auto,constexprare fine. internal(=static) on all file-scoped symbols — defined inmain/types.hpp.- Logging: use
ESP_LOGI/ESP_LOGW/ESP_LOGEonly — neverprintf().- Because of Unity Build, tag variables must have unique names per file:
kTagHttpServer,kTagMain, etc. — never use a sharedTAG.
- Because of Unity Build, tag variables must have unique names per file:
- Seed data:
seed_users()/seed_tasks()must be inside#ifndef NDEBUGguards. - 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 infrontend/src/app.css(@theme). - Svelte 5 runes only —
$state,$derived,$effect,$props,$bindable. Noexport let,onMount,onDestroy,writable, or.subscribe(). $state()for values the template reads. Plainletfor 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.jsviatrackedFetch()— never rawfetch(). - 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.mdandGEMINI.mdup 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.