File size: 7,173 Bytes
62fead0 565e57b a300a19 565e57b 62fead0 a300a19 62fead0 a300a19 565e57b a300a19 62fead0 565e57b 62fead0 565e57b 62fead0 a300a19 565e57b a300a19 565e57b a300a19 565e57b a300a19 565e57b a300a19 62fead0 a300a19 565e57b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# 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 discovery-based creature collection game called "Pictuary". It uses the latest Svelte 5 with runes syntax (`$state()`, `$derived()`, etc.).
### Main Features
- **Monster Discovery**: Upload images β AI identifies objects and generates/retrieves canonical "Piclets"
- **Canonical System**: Each real-world object has ONE canonical Piclet, with variations tracked
- **Collection Management**: Track discovered Piclets with metadata (discoverer, rarity, variations)
- **Activity Feed**: Leaderboard showing top discoverers and recent finds
- **Server Integration**: Connects to `../piclets-server/` for canonical Piclet database
## 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` (discovery), `Pictuary.svelte` (collection), `Activity.svelte` (leaderboard/feed)
- **Monster Discovery**: `PicletGenerator.svelte`, `PicletResult.svelte` with canonical/variation detection
- **Server Integration**: Services for canonical Piclet lookup and creation
- **Piclet Management**: `PicletCard.svelte`, `PicletDetail.svelte` with discovery metadata
- **Database**: IndexedDB with `schema.ts` for local caching + server sync for canonical data
### 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**: Hybrid approach - IndexedDB for local state, server API for canonical Piclets
6. **Discovery Flow**: Caption β Extract object β Server lookup β Return canonical/variation/new
### 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` (configured for object identification)
- **Qwen Text Generation**: For generating Piclet concepts from object captions
### Server Integration
- **Endpoint**: `../piclets-server/` (local development)
- **Canonical Lookup**: POST `/api/piclets/search` with object keywords
- **Create Canonical**: POST `/api/piclets/canonical` for new discoveries
- **Create Variation**: POST `/api/piclets/variation` with canonicalId
- **Activity Feed**: GET `/api/activity/recent` for global discoveries
**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
### Discovery Architecture
#### Object Identification Flow
1. **Image Caption**: Joy Caption extracts object type and visual attributes
2. **Object Extraction**: Parse caption for primary object ("pillow", "pyramid", etc.)
3. **Server Lookup**: Search for exact match or close variations
4. **Response Types**:
- **Exact Match**: Return existing canonical Piclet + increment scan count
- **Close Match**: Create variation of canonical + link to parent
- **No Match**: Create new canonical Piclet + register discoverer
#### Rarity Calculation
- Track `scanCount` per canonical Piclet
- Rarity score = 1 / scanCount (lower scan count = higher rarity)
- Display rarity tiers: Common, Uncommon, Rare, Epic, Legendary
## 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
### Discovery System Issues
- **Object extraction**: Ensure Joy Caption is set to "Descriptive" mode with focus on object type
- **Server connection**: Verify `../piclets-server/` is running on expected port
- **Variation detection**: Check keyword matching algorithm for false positives
- **Rarity calculation**: Ensure scanCount is properly incremented on each discovery
### Performance
- **Large image files**: Consider image compression before upload
- **Server latency**: Cache canonical Piclets locally after first fetch
- **Search optimization**: Use keyword indexing for O(1) lookups
- **Activity feed**: Paginate results, cache recent discoveries
## Implementation Strategy
### Caption Processing
```typescript
// Example caption processing for object extraction
const caption = "A velvet blue pillow with golden tassels on a couch";
const primaryObject = extractObject(caption); // "pillow"
const attributes = extractAttributes(caption); // ["velvet", "blue"]
```
### Server Communication
```typescript
// Canonical lookup
const result = await fetch('/api/piclets/search', {
method: 'POST',
body: JSON.stringify({
object: 'pillow',
attributes: ['velvet', 'blue']
})
});
// Response types
interface CanonicalMatch {
type: 'exact' | 'variation' | 'new';
piclet: PicletInstance;
canonicalId?: string;
discoveredBy?: string;
scanCount: number;
}
```
### Database Schema Updates
- Remove: level, xp, hp, attack, defense, speed, moves, battleStats
- Add: canonicalId, isCanonical, discoveredBy, discoveredAt, scanCount, variations[]
- Keep: typeId, primaryType, tier, imageUrl, description, concept
## 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
- Hybrid storage: IndexedDB for local cache, server for canonical truth
- Object abstraction level is critical - "pillow" not "decorative cushion"
- Variations limited to 2-3 meaningful attributes (material, style, color) |