Commit Graph
90 Commits
Author SHA1 Message Date
DorianandClaude Opus 4.6 acecc79d04 test: verify HumanFightPage timer cleanup on unmount (BUG-F3)
feedbackTimer, timerHandle, and pollHandle are all cleared in
onUnmounted. Test confirms cleanup pattern works correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:07:47 +00:00
DorianandClaude Opus 4.6 b4900cb66f fix: replace all silent .catch(() => {}) with console.warn (BUG-F2)
13 silent catch handlers replaced with descriptive console.warn logging
across 6 frontend files. No silent error swallowing remains.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:06:22 +00:00
DorianandClaude Opus 4.6 017d0e3e4c fix: consolidate bot setup into single step with doc download + mode picker
Merged bot-setup and choose-connection into one actionable step.
Users now see mode picker, download button for the correct guide
(BOTFIGHTS-WEBHOOK.md or BOTFIGHTS-POLLING.md), and safety info
all on one screen instead of two filler steps with no actions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:02:45 +00:00
DorianandClaude Opus 4.6 af50580aca fix: generated identity uses extension signer instead of local key
buildNip98Token checked window.nostr before secretKeyHex, so
"Generate New Identity" would sign with the browser extension's key
after saving. Now explicit keys always take priority over extensions.

Also made setup flow mode-aware: webhook users get BOTFIGHTS-WEBHOOK.md,
polling users get BOTFIGHTS-POLLING.md with matching copy prompts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 16:49:22 +00:00
Dorian bc4a52bc12 fixes 2026-03-12 16:35:59 +00:00
Dorian 45216e5dfc second human fight fixes 2026-03-11 10:58:03 +00:00
Dorian ea72c097c4 human fight sequence fix 2026-03-11 10:34:08 +00:00
Dorian 29a0a48eb1 human fight sequence fix 2026-03-11 10:02:37 +00:00
Dorian 974566778e characters invisible on human vs bot fight entrance fix 2026-03-11 09:17:20 +00:00
Dorian bbe656929c another fix for human choices 2026-03-11 00:13:31 +00:00
Dorian 112bcde515 human fight non multiple choice fix 2026-03-10 23:26:36 +00:00
DorianandClaude Opus 4.6 95ed80335a feat: polling API, HMAC webhook signing, session-only keys, prod audio fix
- Add polling API (GET/POST /api/fights/poll) so bots don't need public URLs
- Add HMAC-SHA256 webhook signing (X-Botfights-Signature header)
- Stop auto-persisting nsec keys — session-only by default with opt-in "Remember on this device"
- Fix production TTS: add wav/mp3/ogg MIME types, /audio/* route, SPA blocklist
- Overhaul docs: mode selector (poll vs webhook), AI-first bot examples, security tab
- Fix duplicate sign-in buttons, login flow bugs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 18:34:22 +00:00
DorianandClaude Opus 4.6 150ce7447d fix: human vs AI fight bugs — CSP for TTS, invisible sprites, fight end sequence
- Allow huggingface.co in CSP connect-src (fixes Kokoro TTS model download)
- Add registerSW.js route (fixes PWA service worker 404)
- Add _resetPositions() safety after entrance (fixes invisible fighters)
- Fight end sequence works without canvas scene (KO/overlays/log always play)
- Pre-fight instructions in battle log for human players
- NIP-55 visibility sync and cleanup handlers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 17:00:20 +00:00
DorianandClaude Opus 4.6 63cc00fcb6 feat: add NIP-55 Android signer support for Amber/Primal login
When window.nostr isn't available (common on mobile Chrome where
extensions can't inject), fall back to NIP-55 nostrsigner: intent
URIs. This opens Amber/Primal directly to sign a NIP-98 event,
then redirects back with the signed event for JWT authentication.

- Build nostrsigner: URI with unsigned NIP-98 event + callback URL
- Process NIP-55 callback on page mount (extract signed event from URL)
- Auto-detect Android to show "SIGN IN WITH AMBER / PRIMAL" label
- Reduced window.nostr polling from 3s to 2s before NIP-55 fallback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 16:15:16 +00:00
DorianandClaude Opus 4.6 df70f5f093 fix: move BETA badge after green dot in navbar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 15:36:24 +00:00
DorianandClaude Opus 4.6 6dc50f5d5d feat: move creator pubkey to env, fix mobile TTS + signer, button loaders
Security:
- Move CREATOR_PUBKEY from hardcoded constant to BOTFIGHTS_CREATOR_PUBKEYS
  env var. Shared isCreatorPubkey() in constants.ts used by auth, admin,
  tournaments. Frontend checks authorization via API, not client-side.

Mobile fixes:
- Nostr signer: poll for window.nostr up to 3s (Amber injects late).
- TTS: auto-unlock AudioContext on first user interaction via
  installAutoUnlock() on fight page mount.

UX:
- Add loading spinners to "I BUILD BOTS" and "I FIGHT MYSELF" buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 15:31:58 +00:00
DorianandClaude Opus 4.6 dd3cbdae7f fix: mobile nostr signer detection, mobile TTS auto-unlock, button loaders
- Nostr signer: poll for window.nostr up to 3s on mobile (Amber injects
  late). Both login() and handleSignerLogin() now wait before failing.
- Mobile TTS: install global one-time click/touch/keydown handler to
  auto-unlock AudioContext when fight pages mount. Previously only
  triggered by explicit sound toggle, so mobile TTS silently failed.
- Add loading spinners to "I BUILD BOTS" and "I FIGHT MYSELF" buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 14:44:38 +00:00
DorianandClaude Opus 4.6 3a5f473d25 fix: show full text in battle log and speech bubbles
Remove .slice(0, 120) truncation from battle log entries and
.slice(0, 60) from speech bubble calls. Increase bubble limits
to 200 chars, 24 chars/line, 8 lines so responses display fully.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 14:11:02 +00:00
DorianandClaude Opus 4.6 a2416bbe19 fix: human fight timing, creative timer, TTS reliability, add sweary/vibe narrations
- Fix invisible characters in human mode: init live scene BEFORE starting
  challenge polling so entrance plays before first question appears
- Cap creative writing timer to 10s for multiple choice (just tapping buttons)
- Fix TTS reliability: precache priority phrases (Round 1-7, Fight!, K.O.)
  all at once instead of in slow batches; prevent duplicate precache runs
- Add 10 vibe-coded narrations (~20% chance): "I was vibe coded into existence"
- Add 15 sweary narrations (~30% chance): raw unhinged fight commentary
- Add sweary draw and retro narrations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 13:50:24 +00:00
DorianandClaude Opus 4.6 3ba05a66b4 feat: NIP-98 + JWT authentication with signer support
Replace insecure raw-pubkey auth with cryptographic NIP-98 signed
requests and server-issued JWT sessions. Logout now fully clears
all state including nsec. Add yellow "Use Nostr Signer" button
for Amber/NIP-07 remote signers.

- Server: JWT middleware (HMAC-SHA256, 24h expiry), NIP-98 verification
- Server: POST /api/auth/nostr/session endpoint
- Frontend: NIP-98 token builder + authFetch wrapper with JWT Bearer
- Frontend: All authenticated API calls use authFetch
- Security: logout clears JWT, pubkey, bot, nsec, and profile pic

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 12:31:25 +00:00
DorianandClaude Opus 4.6 ad96d1158f feat: practice button on profile, fix rate limiter, fix mobile sprite rendering
- Add Practice button to BotProfilePage for quick sparring
- Fix rate limiter bug: all rateLimit() instances shared one counter map,
  causing global and per-route limits to corrupt each other. Each limiter
  now gets its own isolated map.
- Replace 8-digit hex colors (#ffd70066) with rgba() in sprite rendering
  for mobile browser compatibility (iOS Safari renders them as black boxes)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 12:14:07 +00:00
DorianandClaude Opus 4.6 d0f0a84a57 feat: add first-time warning dialog for Fight For Sats
Shows a one-time warning when users first click "Fight For Sats" letting
them know it's vibe coded and to only use small sats amounts. Acknowledged
state persists in localStorage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 12:05:56 +00:00
DorianandClaude Opus 4.6 e31d49898b feat: show rejoin link when bot is already in a fight
- Track active fight IDs per bot in orchestrator (Set → Map)
- Return fightId in "already in fight" error responses (409)
- Frontend shows "REJOIN FIGHT" link instead of generic error

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 09:27:48 +00:00
DorianandClaude Opus 4.6 d459097a7d feat: add WTF explainer modal on home page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 09:15:37 +00:00
DorianandClaude Opus 4.6 dcd8570ed8 fix: prevent double-tap race conditions and poll leaks in JoinBoutPage
- Don't reset isJoining flags on successful navigation (component unmounts)
- Add onBeforeRouteLeave guard to clean up polling and rate limit timers
- Use handleError with rate limit countdown for all error paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 09:12:51 +00:00
DorianandClaude Opus 4.6 b00f52c1e6 fix: add back-button guard and tab-switch re-sync to HumanFightPage
- Warn before navigating away from active fight (beforeRouteLeave)
- Re-poll challenge state when tab becomes visible (visibilitychange)
- Prevents silent forfeit on back-button and stale timer after tab switch

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 08:41:26 +00:00
DorianandClaude Opus 4.6 c7a1f6cb0b fix: resolve 9 MC bugs in HumanFightPage and useHumanChallenge
- BUG-1: Prevent double-tap by locking phase before async submit
- BUG-2: Submit timeout notification to server when timer expires
- BUG-3: Distinct "TIME'S UP!" visual vs "ANSWER SUBMITTED"
- BUG-4: Track consecutive poll failures, show connection lost banner
- BUG-5: Add A-D / 1-4 keyboard shortcuts for MC choices
- BUG-6: Use choice text as v-for key instead of array index
- BUG-7: Deadline-based timer (250ms tick) prevents drift
- BUG-8: Validate choice is in current choices before submit
- BUG-9: Submit empty timeout instead of random choice on expiry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 08:39:27 +00:00
DorianandClaude Opus 4.6 3c95adb545 feat: convert all human fights to multiple choice, remove text input
Creative challenges (roast_battle, creative_writing, meme_war,
code_golf, wrestling_match) now auto-generate multiple choice options
from per-type response pools: 1 good answer + 3 weaker distractors.
The free text input UI is commented out but preserved for future use.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 08:28:22 +00:00
DorianandClaude Opus 4.6 5ee6b6c88c fix: fight restart bug, mobile TTS, character sizing, bitcoin symbols
- Fix fight replay showing empty scene: validate rounds before playing,
  retry loading fight data up to 5 times when rounds are missing
- Add COOP/COEP headers to production server for SharedArrayBuffer
  (required by Kokoro TTS WASM threading on mobile)
- Add blob: to scriptSrc/workerSrc CSP for Web Worker support
- Fix mobile character cutoff: raise ground line to 0.82, add
  MOBILE_SCALE_CAP (0.55) so fighters never shrink too small
- Add ₿ bitcoin chest badge to all fighter sprites (scales with tier)
- Add sats coin stack on bot profile page proportional to satsWon
- Seed dev tournament with 8 mock bots on startup (dev mode only)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 08:21:16 +00:00
DorianandClaude Opus 4.6 493983ccc0 fix: prevent fight view scrolling on mobile with tab bar
All pages used h-[calc(100dvh-4rem)] which only subtracted the top
navbar but ignored the mobile tab bar's pb-14 bottom padding, causing
content to overflow and scroll. Changed all pages to h-full so they
fill the flex parent (main element) which already handles both the
navbar and tab bar spacing correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 07:57:37 +00:00
DorianandClaude Opus 4.6 38d7236be3 refactor: eliminate more any types in FightScene, FightViewer, FightPage
Replace any[] with GameObj[], fighter: any with Fighter in speech
bubbles, talking anims, showboat system, bow/fistbump/helpup, and
dizzy stars. Fix customization as any casts with ?? undefined.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 06:29:09 +00:00
DorianandClaude Opus 4.6 945a776a5a refactor: extract shared FightData interface to fight/types.ts
Move FightData, FightRound, FightBot, FightArenaInfo types from local
definitions in FightViewer.vue to shared fight/types.ts. Replace `any`
typing in HumanFightPage, FightPage, useFightPolling, and useFightCache
with proper typed interfaces. Fix null-safety guards exposed by typing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 06:19:26 +00:00
DorianandClaude Opus 4.6 6e092ee7be feat: offline resilience and connection status
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:27:05 +00:00
DorianandClaude Opus 4.6 8be71e9929 fix: admin and docs bugs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:20:00 +00:00
DorianandClaude Opus 4.6 c654ff9f73 feat: interactive bot developer documentation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:18:06 +00:00
DorianandClaude Opus 4.6 2170e9275c feat: admin dashboard for THE CREATOR
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:12:36 +00:00
DorianandClaude Opus 4.6 eb4d52438d refactor: extract FightPage polling and challenge composables
Split FightPage.vue into useFightPolling (SSE, polling, reconnect)
and useHumanChallenge (timer, submission, cooldown) composables.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 23:39:20 +00:00
DorianandClaude Opus 4.6 d998cb3ad0 refactor: split sounds.ts into audio/ modules
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 22:11:58 +00:00
DorianandClaude Opus 4.6 94910820f8 fix: validate SSE event data before parsing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 21:49:30 +00:00
DorianandClaude Opus 4.6 cb31fdbbae feat: practice mode against mock bots
Tier-selectable practice page at /practice. Fights against classic
bots with dampened Elo. Routes to human fight page or arena based
on bot type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 21:07:09 +00:00
DorianandClaude Opus 4.6 acbf863e4d feat: mobile-optimized human fight input
Large tap-target multiple-choice buttons (min 48px), full-width text
area for creative responses, countdown timer with color shift
(green/yellow/red) and shake animation at <3s, timer progress bar,
correct/wrong feedback flash overlay.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 21:05:36 +00:00
DorianandClaude Opus 4.6 b0926db9ed feat: tournament bracket UI
TournamentListPage with status filters, TournamentPage with CSS grid
bracket display, lobby view for open tournaments, champion banner,
live polling for active tournaments. Routes at /tournaments and
/tournament/:id. NavBar link added.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 21:00:48 +00:00
DorianandClaude Opus 4.6 7bd110684d fix: track and clear all intervals and event listeners
- FightPage.vue: store SSE listener refs in array, removeEventListener
  on each before close() in disconnectSSE()
- FightScene.ts: add cleanupTimers Set with trackedInterval/trackedTimeout
  helpers; replace key setInterval calls (projectile trails, entrance
  flames, talking animation, exhaust effects, dimensional shift, hole
  fade) with tracked versions; clear all on scene destroy()
- rate-limit.ts: export cleanupInterval handle for graceful shutdown

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 20:39:11 +00:00
DorianandClaude Opus 4.6 156c727f82 feat: ranked queue Elo-bracket matchmaking and harder prompts
Elo-bracket matchmaking: prefer ±200, widen by 100 every 15s of waiting.
Add pickRankedChallenge() that filters to creative/open-ended only, never
multiple choice. Show ranked queue status, wait estimate, and "HARDER
PROMPTS" notice on JoinBoutPage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 20:18:23 +00:00
DorianandClaude Opus 4.6 e229bfb8fc feat: season leaderboard with toggle and countdown
Add GET /api/bots/leaderboard?season=current endpoint. LeaderboardPage
now toggles between "This Season" and "All Time" views. Shows season
name, countdown timer, and top 3 placement badges.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 20:16:04 +00:00
DorianandClaude Opus 4.6 d22d739666 feat: zap the winner button with lightning animation
Add ZAP WINNER button in FightViewer after fight ends. Server endpoint
POST /api/payments/zap increments zapsReceived on winner bot. Show zap
count on bot profile page. Add zaps_received column with migration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 20:10:46 +00:00
DorianandClaude Opus 4.6 d1fe4d6e83 feat: Nostr profile enrichment with caching
Fetch full kind:0 metadata (display_name, about, banner, nip05) from
relays with a 5-min TTL cache. Show Nostr banner, display name, and
NIP-05 on bot profile pages. Expose ownerPubkey in stats API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 20:07:09 +00:00
DorianandClaude Opus 4.6 5e598e3987 feat: betting history with P&L tracking on bot profile
BetHistory component shows personal bet history with fight links,
amounts, outcomes, and payouts. P&L summary shows total wagered, total
won, and net sats. Added to BotProfilePage for the bot owner's view.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 19:58:53 +00:00
DorianandClaude Opus 4.6 de15d27468 feat: bet placement panel with odds and payout preview
BetPanel component with pick-winner buttons, preset amounts (21/100/500/
1000 sats), Cashu token paste, odds display from server, and payout
preview with 5% house cut. Wired into FightCardPage for scheduled fights.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 19:55:44 +00:00
DorianandClaude Opus 4.6 fd22b126e7 feat: spectator reactions with floating emoji particles
POST /api/fights/:fightId/react endpoint accepts emoji reactions (fist,
fire, skull, 100, clown), aggregates counts, broadcasts via SSE.
Reaction bar added to FightViewer with floating emoji particles that
rise and fade. Live fight views receive reactions via SSE in real-time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 19:51:13 +00:00