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
# 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 vialang="ts"
in script tags - Main entry:
src/main.ts
→ mountssrc/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
- State Management: Use
$state()
rune for reactive state - TypeScript: All components should use
<script lang="ts">
- Imports: Use ES module imports, components are default exports
- Styling: Component styles are scoped by default, global styles in
src/app.css
- 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:
// 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:
// 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:
- Zephyr-7B: Direct connection to
Fraser/zephyr-7b
space for all text generation - Direct API calls: Components use
zephyrClient.predict("/chat", [...])
directly - 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