# AGENTS.md This file provides guidance to AI coding agents when working with code in this repository. ## Repository Structure This is a monorepo with **backend** and **frontend** directories. ## Agent Skills Use repository skills when applicable: - `svelte-code-writer`: required for creating, editing, or analyzing `.svelte`, `.svelte.ts`, and `.svelte.js` files. - `frontend-design`: use for frontend UI, page, and component design work. - `conventional-commit`: use when drafting commit messages that follow Conventional Commits. - `gemini-api-dev`: use when implementing Gemini API integrations, multimodal flows, function calling, or model selection details. When editing frontend code, always follow `docs/frontend-design-cookbook.md` and update it in the same change whenever you introduce or modify reusable UI patterns, visual rules, or shared styling conventions. ## Commit Guidelines This repository uses Conventional Commits (e.g., `feat(api): ...`, `fix(frontend): ...`, `test(models): ...`). Always format commit messages accordingly and ensure you include the correct scope to indicate which part of the monorepo is affected. ## Commands Run the backend from the `backend/` directory: ```bash # Backend cd backend && uv run python main.py # Linting / formatting cd backend && uv run ruff check . cd backend && uv run black . cd backend && uv run isort . ``` Run the frontend from the `frontend/` directory: ```bash # Frontend cd frontend && pnpm dev # Type checking / linting / formatting cd frontend && pnpm check cd frontend && pnpm lint cd frontend && pnpm format ``` No test suite exists yet (backend has some test files but they're not integrated into CI). ## Architecture **innercontext** collects personal health and skincare data and exposes it to an LLM agent. **Backend Stack:** Python 3.12, SQLModel (0.0.37) + SQLAlchemy, Pydantic v2, FastAPI, PostgreSQL (psycopg3). **Frontend Stack:** SvelteKit 5, Tailwind CSS v4, bits-ui, inlang/paraglide (i18n), svelte-dnd-action. ### Models (`backend/innercontext/models/`) | File | Tables | |------|--------| | `product.py` | `products`, `product_inventory` | | `health.py` | `medication_entries`, `medication_usages`, `lab_results` | | `routine.py` | `routines`, `routine_steps` | | `skincare.py` | `skin_condition_snapshots` | **`Product`** is the core model. JSON columns store `inci` (list), `actives` (list of `ActiveIngredient`), `recommended_for`, `targets`, `incompatible_with`, `synergizes_with`, `context_rules`, and `product_effect_profile`. The `to_llm_context()` method returns a token-optimised dict for LLM usage. **`ProductInventory`** tracks physical packages (opened status, expiry, remaining weight). One product → many inventory entries. **`Routine` / `RoutineStep`** record daily AM/PM skincare sessions. A step references either a `Product` or a free-text `action` (e.g. shaving). **`SkinConditionSnapshot`** is a weekly LLM-filled record (skin state, metrics 1–5, active concerns). ### Key Conventions - All `table=True` models use `Column(DateTime(timezone=True), onupdate=utc_now)` for `updated_at` via raw SQLAlchemy column — do not use plain `Field(default_factory=...)` for auto-update. - List/complex fields stored as JSON use `sa_column=Column(JSON, nullable=...)` pattern (DB-agnostic; not JSONB). - `model_validator(mode="after")` **does not fire** on `table=True` SQLModel instances (SQLModel 0.0.37 + Pydantic v2 bug). Validators in `Product` are present for documentation but are unreliable at construction time. - `backend/skincare.yaml` is a legacy notes file — ignore it, it is not part of the data model and will not be imported. - `_ev()` helper in `product.py` normalises enum values when fields may be raw dicts (as returned from DB) or Python enum instances.