# AGENTS.md — Instructions for AI agents working in this repo Mindlist: Vite + React 19 + TS + Tailwind v4 + Dexie PWA, Capacitor 8 Android wrapper. Default AI model (app + agents): `deepseek/deepseek-v4.1-flash` via OpenRouter. ## Golden commands (run from repo root) ```bash npm install npm run dev # http://localhost:5173 npm test # vitest, must be green npm run build # tsc -b + vite build; PWA in dist/ npx cap sync android cd android && export JAVA_HOME=/opt/homebrew/opt/openjdk@21 ANDROID_HOME=$HOME/Library/Android/sdk ./gradlew assembleDebug # or assembleRelease (needs keystore, see README) ``` Toolchain notes: JDK **21** for Gradle (17 also installed, 26 breaks Gradle). SDK root on this machine is a symlink: `~/Library/Android/sdk -> /opt/homebrew/share/android-commandlinetools`. Device install: `adb install -r `; Pixel 9 Pro attached. Screenshots: `adb exec-out screencap -p > /tmp/x.png`. SVG→PNG rendering without extra deps: headless Chrome `--screenshot` at 512px, downscale with `sips -z ` (Chrome enforces min window width — never screenshot small sizes directly). ## Hard rules 1. **Never commit secrets.** Blocked by `.gitignore`: `Openrouter.md`, `**/*.keystore`, `**/keystore.properties`, `node_modules/`, `dist/`, `*.apk`, `android/local.properties`. Before every commit, run `git status --short` and grep the staged diff for `sk-or-v1-[A-Za-z0-9]{8,}`. 2. **Never hardcode API keys.** BYOK only — key comes from `localStorage` (`mindlist.or.key`), model from `mindlist.or.model` w/ `DEFAULT_MODEL` fallback in `src/lib/openrouter.ts`. 3. **Release keystore is irreplaceable** (`android/mindlist-release.keystore` + `keystore.properties`, untracked). Never delete, move, or regenerate. Remind the human to keep backups. 4. **No new dependencies without need.** Prefer existing: Dexie, Tailwind, lucide-react, zod. 5. **Accessibility bar:** 44px touch targets, `bg-teal-700`+ for white text (never `bg-teal-500` + white), labels for all inputs, `role="dialog"` + Esc on sheets, `:focus-visible` styles. See `src/index.css`. ## Working agreements (how this repo was built) - **Builder/critic loop:** implement → run `npm test` + `npm run build` → spawn one design critic + one functionality critic (subagents, read-only) scoring 0–10 → fix top items → repeat until avg **≥ 8/10 or 5 iterations**, then stop and report. Same protocol for logo work (`logo/` sources, critic reads rendered PNGs at 512 + 48 + 16px). - **Final assets:** `logo/mindlist-logo-v3.svg` = app logo; `logo/mindlist-logo-foreground.svg` = Android adaptive foreground. Don't add new logo versions without retiring the loop first. - **OpenRouter calls:** always `response_format: { type: "json_object" }`, `HTTP-Referer` + `X-Title` headers, `max_tokens: 2000`; validate with `parsePlanExported` (reconciles `totalMin = Σ steps`); **always** fall back to `heuristicPlan`/`offlineSplit`/`offlineExpand` on any failure — the timer must never strand the user. - **Keep it local-first:** no backend, no analytics, no network calls except `api.openrouter.ai`.