dex/AGENTS.md
chris c7c0f9b6da Pre-launch: CI, community health files, AGENTS.md, screenshots, OG tags
- .github/workflows/ci.yml — npm ci + npm run build on push/PR, with the
  PokéAPI snapshot cached so only the first run pays the fetch cost.
- .github/dependabot.yml — weekly npm, monthly actions, grouped.
- .github/ISSUE_TEMPLATE/ — bug report, feature request, config with
  discussion / upstream-data links.
- CODE_OF_CONDUCT.md — Contributor Covenant 2.1 (contact method is a
  placeholder to fill in).
- SECURITY.md — private reporting + the known dev-only Vite/esbuild advisory.
- AGENTS.md — machine-facing version of CONTRIBUTING for AI coding agents.
- docs/screenshots/ + a strip in the README (resized + pngquant'd, ~240 KB).
- public/og.png + Open Graph / Twitter card meta in index.html.
- .nvmrc (20); gitignore .claude/ .idea/ .vscode/.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
2026-09-10 11:14:01 -04:00

4.6 KiB

AGENTS.md

Guidance for AI coding agents working in this repo. Humans: see CONTRIBUTING.md — this file is the short, machine-facing version of the same rules.

What this is

Pocketdex — an offline-first Pokédex / team builder / save-file tracker. Vanilla JS, no UI framework. Vite 5 + vite-plugin-pwa (Workbox, injectManifest). All data comes from PokéAPI.

Setup & commands

npm install
npm run snapshot        # build src/data/snapshot.json from PokéAPI (git-ignored; required before first build/dev)
npm run dev             # dev server, http://localhost:5173
npm run build           # runs `snapshot` (prebuild) then builds to dist/
npm run preview         # serve the production build — REQUIRED to test the service worker / offline / install
  • Node 20+.
  • There is no lint or test command and no test suite. The build (npm run build) is the only automated check — it must pass. It runs esbuild over every module, so it catches syntax and import errors.
  • npm run snapshot -- --force rebuilds the snapshot even if it's fresh.

Project structure

Path What
src/main.js boot: theme, nav, router, SW registration, install prompt
src/router.js hash router; routes array; each view is () => Promise<Node>
src/views/*.js one file per route (DexGrid, PokemonDetail, TeamView, …)
src/components/*.js reusable DOM pieces (Card, Sprite, TypeChip, CompareTable, …)
src/store/*.js createStore() state, persisted to localStorage under pdx.*
src/data/*.js snapshot loader, pokedex resolver, lazy PokéAPI client, type chart, natures
src/lib/*.js app-agnostic helpers (dom, anim, damage-calc, savedex, swipe, …)
scripts/build-snapshot.mjs the only thing that calls PokéAPI at build time
src/styles/tokens.css palette, type colours, the five themes
src/styles/layout.css everything else

Conventions

  • Build DOM with el() from src/lib/dom.jsel(tag, props, ...children). No template-string HTML, no innerHTML, except the deliberate html: prop for trusted inline SVG.
  • Stores: createStore(key, initial){ get, set, subscribe, replace }. set(fn) replaces state (it does not merge) — spread ...s yourself. In views, subscribe() and call the returned unsub in onTeardown(viewNode, off).
  • Everything is game-aware. The selected game lives in settings.get().versionGroup. If you touch typings, effectiveness, learnsets or evolution, honour that game's generation: typesForGen(), multiplier(atk, def, gen), PokéAPI past_values.
  • Tracking is per game. src/store/selection.js: entry(id) / toggle(id, field) / stats(ids) default to the selected game; favorite and note are global. Don't reintroduce a single global caught set.
  • Respect prefersReducedMotion() (from src/store/settings.js) for any animation.
  • 2-space indent, semicolons, single quotes, trailing commas in multi-line literals. Match the surrounding file; keep comments about why.
  • No new runtime dependencies. Prefer adding to the snapshot over a new runtime fetch.

Adding things

  • Route — new src/views/Foo.js exporting async function Foo() returning a node; add one entry to routes in src/router.js. Add a skeleton if it does async work before first paint.
  • Setting — key + default in src/store/settings.js (and applyTheme() if it affects the document), a field in src/views/SettingsView.js, and add it to the export payload in exportData() if it should survive a backup.
  • Snapshot field — add it in scripts/build-snapshot.mjs, run npm run snapshot -- --force, read it via loadSnapshot(). Keep the snapshot small; it's precached on every install.

Do not

  • Commit dist/ or src/data/snapshot.json (both git-ignored).
  • Commit Pokémon sprites, artwork, audio, ROMs or save files. All imagery is fetched at runtime from PokéAPI.
  • Add analytics, telemetry, ads, tracking, or "sign in" flows.
  • Add a framework or a build step that isn't Vite.
  • Break offline-first: the grid, search, filters and game switching must work with no network.

Verifying a change

npm run build must pass. Then sanity-check by hand: the dex grid (filters, sort, catching from a card), switching games (numbers + typings update), a detail page (all tabs, form switch), and npm run preview offline (DevTools → Network → Offline → reload). Check light and dark theme and a mobile-width viewport.