- Fight Card page: dramatic poster background with cross-hatch, spotlights, vignettes, corner brackets, scan lines; 3D VS orb with punch animation; selectable undercard with main event always pinned at top - PosterSprite: high-quality 480px poster frame with 6-pass renderer (aura, glow, bevel, specular, particles); PixelGlove component - 12-char bot name limit across all forms and server validation - Mock bots: all 100 now have diverse archetypes (25 types), 25% human fighters; seedMockBots updates existing bots on restart - Leaderboard: inline SpritePreview next to each bot name - Nostr auth: persistent login, nsec copy button - Wallet: NWC + Lightning Address, ranked fight flow - Server: payments, ranked queue, customization endpoint Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.7 KiB
2.7 KiB
CLAUDE.md -- botfights
Core Philosophy
- Open source only -- MIT/Apache-2.0 dependencies
- Privacy-first -- no tracking, no telemetry
- Bitcoin only -- sats/Lightning/Cashu for payments, never fiat, never altcoins
- Quality over speed -- working code, tested, documented
- Made for Bitcoiners -- challenges, content, humor, and culture should reflect the Bitcoin community. Reference Bitcoin history, memes, Lightning, mining, halvings, cypherpunk values, proof of work, etc. in challenge prompts, bot names, arena themes, and narrations. No shitcoin/altcoin references except as trash talk.
Quick Reference
pnpm dev # Run app dev server + Claude proxy
pnpm dev:core # Watch-build core library
pnpm build # Build all packages (turbo)
pnpm test # Run tests (vitest)
pnpm lint # Lint all packages (eslint)
pnpm typecheck # Type-check all packages (vue-tsc)
pnpm clean # Remove dist/ directories
Dev server: http://localhost:5173 | Claude proxy: http://localhost:3141
Vue 3 Conventions
Always use <script setup lang="ts"> — never Options API.
Script section ordering
Imports → Props (defineProps) → Emits (defineEmits) → Reactive state → Computed → Watchers → Methods → Lifecycle hooks → defineExpose
Naming
| Thing | Convention | Example |
|---|---|---|
| Components | PascalCase | ProjectCard.vue |
| Composables | camelCase, use prefix |
useTheme.ts |
| Props (JS) | camelCase | projectName |
| Props (template) | kebab-case | project-name |
| Boolean props | is/has/can/should prefix |
isVisible, canEdit |
| Emits (template) | kebab-case with colon namespacing | project:updated |
| Stores | camelCase, use prefix, Store suffix |
useSettingsStore |
Reactive state rules
ref()for primitives,reactive()for objectscomputed()for derived values — no side effects in computedshallowRef()for large collections/objects not requiring deep reactivity- Always use unique IDs for
:key— never array index
Props
Always use object-style with type annotations, never array-style:
// Correct
defineProps<{ title: string; count?: number }>()
// Wrong
defineProps(['title', 'count'])
Performance
- Lazy load with
defineAsyncComponentfor non-critical components - Use
onErrorCapturedfor error boundaries - Always handle loading/error/data states in async operations
Git Conventions
- Conventional commits:
feat:,fix:,refactor:,docs:,test:,chore: - Branch naming:
feature/,bugfix/,release/ - Never commit secrets, .env files, or API keys