# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Bibdle is a daily Bible verse guessing game built with SvelteKit 5. Players read a verse and try to guess which book of the Bible it comes from. The game provides feedback hints (Testament match, Section match, Adjacent book, etc.) similar to Wordle-style games. Progress is stored locally in the browser and a new verse is generated daily. You are able to use the Svelte MCP server, where you have access to comprehensive Svelte 5 and SvelteKit documentation. Here's how to use the available tools effectively: (Make sure you use the Svelte agent to execute these commands) ## Available MCP Tools: ### 1. list-sections Use this FIRST to discover all available documentation sections. Returns a structured list with titles, use_cases, and paths. When asked about Svelte or SvelteKit topics, ALWAYS use this tool at the start of the chat to find relevant sections. ### 2. get-documentation Retrieves full documentation content for specific sections. Accepts single or multiple sections. After calling the list-sections tool, you MUST analyze the returned documentation sections (especially the use_cases field) and then use the get-documentation tool to fetch ALL documentation sections that are relevant for the user's task. ### 3. svelte-autofixer Analyzes Svelte code and returns issues and suggestions. You MUST use this tool whenever writing Svelte code before sending it to the user. Keep calling it until no issues or suggestions are returned. ### 4. playground-link Generates a Svelte Playground link with the provided code. After completing the code, ask the user if they want a playground link. Only call this tool after user confirmation and NEVER if code was written to files in their project. ## Tech Stack - **Framework**: SvelteKit 5 with Svelte 5 (uses runes: `$state`, `$derived`, `$effect`, `$props`) - **Styling**: Tailwind CSS 4 - **Database**: SQLite with Drizzle ORM - **Auth**: Session-based authentication using @oslojs/crypto (SHA-256 hashed tokens) - **Deployment**: Node.js adapter for production builds - **External API**: bible-api.com for fetching random verses ## Development Commands ```bash # Start development server bun run dev # Type checking bun run check bun run check:watch # Build for production bun run build # Preview production build bun run preview # Database operations bun run db:push # Push schema changes to database bun run db:generate # Generate migrations (DO NOT RUN) bun run db:migrate # Run migrations (DO NOT RUN) bun run db:studio # Open Drizzle Studio GUI ``` ## Architecture ### Database Schema (`src/lib/server/db/schema.ts`) - **user**: User accounts with id and age - **session**: Auth sessions linked to users with expiration timestamps - **daily_verses**: Cached daily verses with book ID, verse text, reference, and date Sessions expire after 30 days and are automatically renewed when less than 15 days remain. ### Bible Data (`src/lib/types/bible.ts`) The `bibleBooks` array contains all 66 Bible books with metadata: - Testament (old/new) - Section (Law, History, Wisdom, Prophets, Gospels, Epistles, Apocalyptic) - Order (1-66, used for adjacency detection) - Popularity (2-10, affects grading - higher is more popular) ### Daily Verse System (`src/routes/+page.server.ts`) The `getTodayVerse()` function: 1. Checks database for existing verse for today's date 2. If none exists, fetches from bible-api.com (random verse + 2 consecutive verses) 3. Caches in database with UTC date key 4. Returns verse with book metadata for the game ### Game Logic (`src/routes/+page.svelte`) **State Management:** - `guesses` array stores game state in localStorage keyed by date - Each guess tracks: book, testamentMatch, sectionMatch, adjacent - `isWon` is derived from whether any guess matches the correct book **Grading System:** ```javascript // Grade formula combines performance + difficulty performanceScore = max(0, 10 - numGuesses) difficulty = 14 - popularity totalScore = performanceScore + difficulty * 0.8 // S: 14+, A: 11+, B: 8+, C: 5+, C-: <5 ``` **Hint System:** - ✅ Green checkmark: Exact match - 🟩 Green square: Section matches - 🟧 Orange square: Testament matches (shared results) - ‼️ Double exclamation: Adjacent book in Bible order - 🟥 Red square: No match ### Authentication System (`src/lib/server/auth.ts`) - Token-based sessions with SHA-256 hashing - Cookies store session tokens, validated on each request - Hook in `src/hooks.server.ts` populates `event.locals.user` and `event.locals.session` - Note: Currently the schema includes user table but auth UI is not yet implemented ## Key Files - `src/routes/+page.svelte` - Main game UI and client-side logic - `src/routes/+page.server.ts` - Server load function, fetches/caches daily verse - `src/lib/server/bible-api.ts` - External API integration for verse fetching - `src/lib/server/bible.ts` - Bible book utility functions - `src/lib/types/bible.ts` - Bible books data and TypeScript types - `src/lib/server/db/schema.ts` - Drizzle ORM schema definitions - `src/hooks.server.ts` - SvelteKit server hook for session validation ## Environment Variables Required in `.env`: - `DATABASE_URL` - Path to SQLite database file (e.g., `./local.db`) ## Deployment The project uses `@sveltejs/adapter-node` for deployment. The build output is a Node.js server that can be run with systemd or similar process managers. See `bibdle.service` and `bibdle.socket` for systemd configuration. ## Important Notes - Uses Svelte 5 runes syntax (`$state`, `$derived`, `$effect`, `$props`) - not stores or reactive declarations - The schema includes authentication tables but the login/signup UI is not yet implemented - Daily verses are cached permanently in the database to ensure consistency - LocalStorage persists guesses per day using the key pattern `bibdle-guesses-${date}` - The game validates book IDs from the API against the hardcoded `bibleBooks` array