# AGENTS.md Guidance for AI agents and contributors working in this repo. Read `README.md` for commands and layout. ## Project priorities (do not erode) 1. **Simplicity** — prefer the smallest, most readable solution. 2. **Few dependencies** — runtime deps stay minimal (today `ejs` + `lucide-static`). Prefer the Node standard library; justify any new dependency; do not add frameworks. The app is **stateless — no database**. Auth/identity/OAuth are **Ory sidecar services** (Kratos/Keto/Hydra, backed by Postgres), reached over their REST APIs with built-in `fetch` — no SDK dependency. New capabilities ship as **plugin folders** under `plugins/` that fetch their data from upstream services, not as core code. See `README.md` for the architecture. 3. **Strict TypeScript** — `tsconfig.json` is strict (incl. `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`, `verbatimModuleSyntax`). Keep it that way. ## Docker only — no host tooling **Everything** (install, typecheck, test, run, build, deploy) goes through Docker / Docker Compose. **Never run `node`, `npm`, or `tsc` on the host.** ```bash docker compose up # dev server, live reload docker compose run --rm web npm run typecheck # strict type check docker compose run --rm web npm test # tests docker compose -f docker-compose.yml up --build -d # production ``` ## Rules - Node 24 runs `.ts` directly (type stripping). Keep all TypeScript **erasable** (`erasableSyntaxOnly` is on): no `enum`, `namespace`, parameter properties, or decorators. Import local modules with their `.ts` extension. - **No build step** and no compiled artifacts — do not add a bundler or `tsc` emit. - Before finishing a change, run the typecheck and tests above; both must pass. - Tests use the built-in `node --test` runner — no test framework dependency. - English everywhere. Keep code comments short and information-dense. - Pin all dependencies and Docker images to exact, human-readable **semantic versions** — never ranges (`^`, `~`) and never digests/hashes. npm deps are kept exact by `.npmrc` (`save-exact=true`) + `npm ci`; the base image by tag (e.g. `node:24.16.0-alpine3.24`).