| Name | Message | Date |
|---|---|---|
| π .claude | 3 hours ago | |
| π .devcontainer | 9 hours ago | |
| π .vscode | 3 hours ago | |
| π scripts | 1 hour ago | |
| π src | 1 hour ago | |
| π static | 1 hour ago | |
| π .gitignore | 1 hour ago | |
| π .npmrc | 3 hours ago | |
| π CLAUDE.md | 2 hours ago | |
| π deno.json | 1 hour ago | |
| π deno.lock | 1 hour ago | |
| π eslint.config.js | 3 hours ago | |
| π package.json | 1 hour ago | |
| π playwright.config.ts | 3 hours ago | |
| π README.md | 3 hours ago | |
| π svelte.config.js | 3 hours ago | |
| π tsconfig.json | 3 hours ago | |
| π vite.config.ts | 3 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. - Extract components when reusable. If a piece of UI is used in two or more places, make it a component. If it's only used once, keep it inline.
- Prefer relative units. Use
remfor component sizing,vw/vh/dvhfor layout and viewport-relative values. Reservepxfor borders and shadows only. - 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 β
localStoragefor the bird collection and user state. Sighting data is small (species, timestamp, coordinates) so localStorage is simpler and sufficient. Migrate to IndexedDB only if binary storage (audio blobs, images) is needed. - 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.