# @kentcdodds/asteroids — agent notes Human overview: [`README.md`](./README.md). - Package app; `kody.app.entry` is `./app/router.ts`. Routes: `/` game, `/about`, `/manifest.webmanifest`, `/sw.js`, `/version.json`, `/health`, and `/a/*` images. No secrets, storage, outbound requests, or `kody:` deps (keep it that way so the capability set stays empty). - Files: `app/game.ts` (game + audio), `app/about.ts`, `app/pwa.ts` (manifest, service worker, client PWA glue), `app/ui.ts` (shared look + head/og tags), generated `app/build-info.ts` and `app/assets.ts`. - **Always run `npm run build` before committing.** `scripts/build-info.mjs` hashes `app/` + `public/` into `BUILD.buildId` (the service-worker cache version and update signal) and embeds `public/` images into `app/assets.ts`. Forgetting it ships stale images and no update prompt. - Art: `npm run art` re-renders `public/og.jpg`, `public/icons/*`, and `.kody/icon.png` from SVG in `scripts/render-art.mjs` with headless Chrome (needs `playwright-core`; set `CHROME_PATH`), then palette-quantizes the PNGs. - og:image URLs are absolute, built from the request's `X-Forwarded-Host`/`Host` (fallback `https://asteroids.kentcdodds.com`). - Service worker: cache `asteroids-`, pages cache-first from that build, manifest network-first. A new worker waits; the page shows UPDATE AVAILABLE and sends `SKIP_WAITING` on tap. First install claims immediately. - All game code lives in `app/game.ts` (`gameScript` inlined into `html`). No layout-shifting text: HUD uses fixed-width spans and the overlay toggles `visibility`. - Public and internet-visible (served at https://asteroids.kentcdodds.com). The only routes are the game page and `/health`; keep it that way, with no storage, secrets, or outbound requests. - Audio is synthesized in `gameScript` with Web Audio (no assets). The AudioContext is created on the first pointer/key gesture. `window.__asteroids.audio` exposes `{ ctx, soundOn, musicOn, step }` for tests. - Test: `npm test` builds `dist/index.html` and runs a headless Chromium smoke test (`scripts/smoke.mjs`) that checks for console/page errors, starts a game, fires and thrusts. It needs `playwright` resolvable. - Icon: `.kody/icon.png` (512px, ship + asteroid), source `.kody/icon.svg` (generated by `npm run art`). - Publish with the local CLI only: `npx @kodycodes/cli package publish @kentcdodds/asteroids`.