| # CLAUDE.md | |
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | |
| ## Project Overview | |
| This is a Svelte 5 + TypeScript + Vite single-page application for a Pokémon-style creature collection game called "Pictuary". It uses the latest Svelte 5 with runes syntax (`$state()`, `$derived()`, etc.). | |
| ### Main Features | |
| - **Monster Generation**: Upload images → AI generates unique creatures ("Piclets") with stats and abilities | |
| - **Battle System**: Turn-based combat between player and AI opponents | |
| - **Collection Management**: Roster of captured Piclets with detailed stats and move sets | |
| - **Creature Cards**: Trading card-style interface with type-based designs | |
| - **Image Processing**: AI-powered image captioning and creature concept generation | |
| ## Essential Commands | |
| ```bash | |
| # Install dependencies | |
| npm install | |
| # Development server with HMR | |
| npm run dev | |
| # Type checking | |
| npm run check | |
| # Production build (outputs to dist/) | |
| npm run build | |
| # Preview production build | |
| npm run preview | |
| # Run tests | |
| npm test | |
| # Run tests with UI | |
| npm run test:ui | |
| ``` | |
| ## Architecture | |
| ### Component Structure | |
| - Components use `.svelte` files with TypeScript support via `lang="ts"` in script tags | |
| - Main entry: `src/main.ts` → mounts `src/App.svelte` | |
| - Reusable components go in `src/lib/` | |
| - Uses Svelte 5 runes syntax (not Svelte 4 syntax) | |
| ### Key Components | |
| - **Pages**: `Scanner.svelte` (main), `Pictuary.svelte` (collection), `Battle.svelte` (combat) | |
| - **Monster Generation**: `MonsterGenerator.svelte`, `MonsterResult.svelte` (redesigned with PicletCard preview) | |
| - **Battle System**: `BattleField.svelte`, `ActionButtons.svelte`, turn-based combat logic | |
| - **Piclet Management**: `PicletCard.svelte`, `PicletDetail.svelte`, `AddToRosterDialog.svelte` | |
| - **Database**: IndexedDB with `schema.ts` defining PicletInstance, BattleMove, Monster types | |
| ### Key Patterns | |
| 1. **State Management**: Use `$state()` rune for reactive state | |
| 2. **TypeScript**: All components should use `<script lang="ts">` | |
| 3. **Imports**: Use ES module imports, components are default exports | |
| 4. **Styling**: Component styles are scoped by default, global styles in `src/app.css` | |
| 5. **Database**: IndexedDB operations in `src/lib/db/` with async functions for CRUD operations | |
| ### Build Configuration | |
| - Vite handles bundling with `vite.config.ts` | |
| - TypeScript config uses project references (tsconfig.json + tsconfig.app.json) | |
| - Production builds go to `dist/` directory | |
| ## External Dependencies | |
| ### Gradio Client Integration | |
| This project uses Gradio Client for connecting to Hugging Face Spaces. **Important**: Use the CDN-based approach, not npm packages. | |
| **Setup in App.svelte:** | |
| ```javascript | |
| // CDN imports are loaded dynamically | |
| import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js"; | |
| window.gradioClient = { Client }; | |
| ``` | |
| **Usage in other files:** | |
| ```typescript | |
| // Access via window.gradioClient (types are declared in vite-env.d.ts) | |
| const client = await window.gradioClient.Client.connect("space-name"); | |
| ``` | |
| **Current Gradio Connections:** | |
| - **Flux Image Generation**: `Fraser/flux` | |
| - **Joy Caption**: `fancyfeast/joy-caption-alpha-two` | |
| - **Zephyr-7B Text Generation**: `Fraser/zephyr-7b` | |
| **Build Notes:** | |
| - DO NOT install Gradio Client via npm (`npm install @gradio/client`) - it causes build failures | |
| - The CDN approach ensures compatibility with Vite bundling | |
| - All Gradio connections should use the established pattern from App.svelte | |
| ### Text Generation Architecture | |
| The project uses a simple, direct approach: | |
| 1. **Zephyr-7B**: Direct connection to `Fraser/zephyr-7b` space for all text generation | |
| 2. **Direct API calls**: Components use `zephyrClient.predict("/chat", [...])` directly | |
| 3. **No fallback complexity**: Simple, reliable single-client architecture | |
| ## Troubleshooting | |
| ### Common Build Issues | |
| - **Gradio Client build failures**: Ensure you're NOT using `npm install @gradio/client`. Use CDN imports only. | |
| - **Type errors**: Run `npm run check` to identify TypeScript issues before building | |
| - **Missing dependencies**: Run `npm install` if packages are missing | |
| ### Monster Generation Issues | |
| - **Name extraction problems**: Check `MonsterGenerator.svelte` - regex should extract content after `# Monster Name` | |
| - **Zephyr-7B connection failures**: Verify `Fraser/zephyr-7b` space is accessible | |
| - **Image processing errors**: Verify Flux and Joy Caption clients are properly connected | |
| ### Performance | |
| - **Large image files**: Consider image compression before upload | |
| - **Slow generation**: Zephyr-7B may take 10-30 seconds for complex monster concepts | |
| - **Battle lag**: IndexedDB operations are async - ensure proper await usage | |
| ## Important Notes | |
| - This is NOT SvelteKit - no routing, SSR, or API routes | |
| - HMR preserves component state (can be toggled in vite.config.ts) | |
| - All paths in imports should be relative or use `$lib` alias for src/lib | |
| - IndexedDB is used for local storage - data persists between sessions |