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)