| Name | Message | Date |
|---|---|---|
| π .claude | 5 hours ago | |
| π .devcontainer | 10 hours ago | |
| π .vscode | 5 hours ago | |
| π src | 5 hours ago | |
| π static | 5 hours ago | |
| π .gitignore | 5 hours ago | |
| π .npmrc | 5 hours ago | |
| π CLAUDE.md | 5 hours ago | |
| π deno.json | 5 hours ago | |
| π deno.lock | 5 hours ago | |
| π eslint.config.js | 5 hours ago | |
| π package.json | 5 hours ago | |
| π playwright.config.ts | 5 hours ago | |
| π README.md | 5 hours ago | |
| π svelte.config.js | 5 hours ago | |
| π tsconfig.json | 5 hours ago | |
| π vite.config.ts | 5 hours ago |
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this project is
BirdGO is an offline-first SPA that works like PokΓ©monGO but for real birds. The user taps to listen; BirdNET (via TensorFlow.js) classifies bird sounds locally in the browser; identified species go into a local collection. No audio or data is sent to any server. Online accounts and leaderboards are a planned future feature.
Commands
All tasks run via Deno. Use deno task instead of npm run.
deno task dev # start dev server
deno task build # production build
deno task preview # preview production build
deno task check # svelte-kit sync + svelte-check (type checking)
deno task lint # ESLint
deno task test # run all Playwright e2e tests
deno fmt # format (spaces, double quotes, includes Svelte components)
Run a single e2e test file:
deno run -A npm:playwright test src/routes/path/to/page.svelte.e2e.ts
Code style
- TypeScript everywhere, full types. No
any, no type assertions unless truly unavoidable. - Nested CSS inside
<style>blocks. Use element and hierarchy selectors (nav a,section > h2) over classes wherever the HTML structure makes the selector unambiguous. Classes only when hierarchy isn't enough. - Semantic HTML. Use
<main>,<nav>,<section>,<article>,<button>,<dialog>, etc. correctly. - No premature component extraction. Keep markup inline until a piece is genuinely reused in two or more places. A component for one caller is noise.
- Simplest possible implementation. No abstractions for hypothetical futures. Three similar lines beat a premature helper.
- Svelte 5 runes only.
$state(),$derived(),$effect(),$props(). The Options API is disabled globally insvelte.config.js.
Architecture
This is a SvelteKit SPA using Svelte 5 with Deno as the runtime and package manager. SvelteKit is used for its component model, routing, and build tooling β not for SSR. All data lives in the browser (IndexedDB).
Key layers
src/routes/β file-based routing.+page.svelteis the page,+layout.sveltewraps child routes.src/lib/β shared code only. Accessed via the$libalias. Subdivide as needed:$lib/audio/,$lib/db/,$lib/model/.- Audio pipeline β Web Audio API β BirdNET (TensorFlow.js TFJS model) β species result. Runs entirely client-side.
- Persistence β IndexedDB for the bird collection and user state. No backend.
- Offline β PWA / service worker (not yet implemented).
Config files
deno.jsonβ Deno tasks and formatter config (fmt-componentunstable flag enables Svelte formatting).package.jsonβ npm-compatible dependency declarations consumed by Deno's npm compatibility layer.svelte.config.jsβ SvelteKit adapter (adapter-auto) and runes enforcement.playwright.config.tsβ e2e tests run against a production build (port 4173), not the dev server. Test files use the.e2e.{ts,js}extension, collocated with their routes.tsconfig.jsonβ extends.svelte-kit/tsconfig.json; strict mode enabled.
Environment
DENO_DIR is set to /home/developer/.cache/deno in .claude/settings.json (the default /deno-dir/ is not writable). This is applied automatically β no manual export needed.