From bb329892794a65b743b984d37ac26b301a4265fa Mon Sep 17 00:00:00 2001 From: Halit Aksoy Date: Fri, 16 Oct 2026 00:44:09 +0300 Subject: [PATCH] docs: add AGENTS.md with setup, checks and pitfalls, and CLAUDE.md pointing to it --- AGENTS.md | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 3 ++ 2 files changed, 104 insertions(+) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..59a1d92 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,101 @@ +# AGENTS.md + +Guidance for coding agents working in this repository. Keep it current: when you learn something that would have +saved time, add it here. + +## Project + +Online Mancala (the Turkish *Mangala* rules) with a web app, an Android/iOS app and a Node backend. + +| Path | What | +|---|---| +| `packages/mancala.js` | Game engine; rules are plug-ins in `src/common/game_rules` | +| `packages/core` | Code shared by the apps: models, WebSocket client (`RTMTWS`), channel names, history helpers, themes, `PitAnimator`, translations (en, tr) | +| `apps/backend` | Express + `ws`: matchmaking, games, auth, saved games, HTTP API | +| `apps/frontend` | React web app, built with Parcel | +| `apps/mobile` | React Native app | +| `apps/keycloak` | Keycloak image with the realm and a Java extension for guest login | +| `apps/postgres` | Init script creating the `keycloak` and `mancala` databases | +| `apps/compose.yaml` | Postgres, Valkey, Keycloak, backend, frontend | +| `config/nginx.conf` | The production server's nginx config (Certbot managed) | +| `docs/specs/` | Specs: `requirements.md`, `design.md`, `tasks.md` | +| `TODO.md` | Open work, known bugs and deployment steps; read it before starting | + +Specs that exist: `keycloak-auth` (login, guests, tokens) and `game-history` (saved games, live games, replay). + +## Running locally + +```sh +yarn build:packages # repo root; builds mancala.js and core +cd apps && docker compose up -d --build postgres valkey keycloak # needs apps/.env, see README.md +cd apps/backend && yarn dev # http://localhost:5005 +cd apps/frontend && yarn dev # http://localhost:1234 (must be 1234, Keycloak only allows that) +``` + +Postgres is on `localhost:5433` (5432 is often taken), Valkey on `6379`, Keycloak on `8080` +(admin console `/admin`). The backend's and frontend's defaults point at these. The mobile app points at production +unless `useLocalServer` is set in `apps/mobile/src/const/config.ts`. + +## Checks + +| What | Command | Notes | +|---|---|---| +| Engine | `cd packages/mancala.js && npx jest` | | +| Core | `cd packages/core && npx jest` | | +| Backend | `cd apps/backend && npx tsc --noEmit -p . && npx jest` | Needs Docker: Postgres and Valkey run in testcontainers | +| Keycloak extension | `cd apps/keycloak/extension && mvn test` | Needs Docker; starts Keycloak with the real realm file | +| Web app | `cd apps/frontend && yarn build` | There is no `tsconfig.json`, so nothing type-checks it; use a temporary one when needed. 3 type errors are known and older than recent work | +| Mobile | `cd apps/mobile && npx tsc --noEmit -p .` and `npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output /tmp/x.bundle` | 11 type errors are known and older than recent work | + +There is no automated end-to-end suite. Changes to the game flow were checked by driving Chrome with +`playwright-core` (installed outside the repo, `executablePath: /usr/bin/google-chrome`) against the local stack. + +## How we work + +- The user writes in Turkish; code, comments, commit messages and specs are in English. +- Larger features start with a spec in `docs/specs//` (requirements with acceptance criteria, design with + decisions and reasons, tasks as a checklist). Implement the tasks in order, one commit each, and tick them. Small + fixes need no spec. When resuming a feature, read its spec and `tasks.md` first. +- Work on feature branches; commit messages follow `type(scope): summary` with a short body. +- Never add AI attribution (Co-Authored-By lines, "Generated with …") to commits or PRs. +- Do not commit files the user changed but did not ask to commit; stage only your own changes (hunks if needed). +- New dependencies get exact versions. + +## Things that are easy to get wrong + +**Packages and builds** +- The apps use `packages/core` and `packages/mancala.js` through `link:` dependencies, i.e. their built `dist`. + After changing a package, run `yarn build` in it (or `yarn dev` to rebuild on change), or the apps use stale code. +- Backend and frontend Docker images are built from the repo root: `docker build -f apps/backend/Dockerfile .`. +- The mobile app uses `RTMTWS` from core (its own `src/rtmt` copy is unused), so changing the core WebSocket client + changes mobile too. Metro needs `watchFolders` and `nodeModulesPaths` (already in `metro.config.js`). + +**Backend** +- User ids: Keycloak users are `kc:`; legacy mobile users are their `userKey`, which is a secret. Anything + saved or listed publicly goes through `publicUserId()`; clients get `toClientGame()`, never spectator ids. +- Live games: memory is the source of truth, Valkey is a write-through copy restored on startup; the backend + assumes a single instance. Finished games are written to Postgres once, with retry when it is down. +- Postgres or Valkey being down must not stop games; reads fall back, writes are retried. +- `RTMT.listenOnClientConnectionChange` adds a listener (several are allowed). +- Jest 27 lacks Node's web globals that testcontainers needs; `tests/support/NodeEnvironment.js` copies them in. +- A Valkey client pointed at a dead port keeps Jest alive for `disconnectTimeout`; tests pass a short one. + +**Web app** +- styled-jsx only scopes JSX written directly in a component's render; elements built in helper functions or + `map` callbacks need `.parent :global(.child)` rules. +- Pages are full-height flex columns: a block with `overflow: hidden` needs `flex-shrink: 0` or it gets squeezed. +- Board components size themselves from the `--board-unit` CSS variable; `BoardView` takes an optional `width`. +- The WebSocket client emits `open` after authentication; anything the server must know about a connection + (spectating a game, live game previews) is sent on `open`, because the server forgets it when a user goes offline. + +**Keycloak** +- The realm file is imported only when the realm does not exist; changes to it must also be made in a running + Keycloak (or recreate the database). +- Listing some `requiredActions` in the realm file replaces Keycloak's whole default list, so the file contains all + of them. +- The guest authenticator uses an internal Keycloak SPI: keep the version in `extension/pom.xml` and `Dockerfile` in + sync and run `mvn test` when upgrading. +- Keycloak sets `Secure` cookies; browsers send them to `http://localhost`, simple HTTP clients do not. + +**Mobile** +- `apps/mobile/release_android.sh` contains signing passwords (see `TODO.md`); do not copy them anywhere. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..ba64777 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,3 @@ +The instructions for this repository are in AGENTS.md, shared by all coding agents: + +@AGENTS.md