Commit graph

7 commits

Author SHA1 Message Date
jedarden
79f3bee8a9 fix(web): serve replays from same-origin /data/ static assets, not R2
Replays are bundled into the Pages deploy as gzipped static assets (B2 stays
the private cold archive). Repoint all replay/card/thumbnail/live.json fetches
off the empty R2 cache and the non-resolving b2.aicodebattle.com onto
same-origin /data/, via a shared fetchReplayFromUrl helper that gunzips
.json.gz with DecompressionStream.

- new web/src/lib/replay-data.ts (REPLAY_BASE, replayUrl, fetchReplayFromUrl)
- replay.ts / embed.ts / pages/embed.ts / playlist-carousel.ts use the helper
- og-tags, bot-card, home, matches, bot-profile, playlists, feedback, ambient,
  api-types: /r2/ -> /data/
- pages.json data_paths updated; friendlier 404 message preserved
- 21 web tests pass; npm run build OK

Closes: bf-5cwi

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 16:41:30 -04:00
jedarden
273736a3f2 fix(web): fix replay viewer routing and embed fallback
Router: strip query string from hash path before route matching, and merge
hash query params (e.g. ?url=) into the params passed to route handlers.
Add /watch/replay route (without :id) so ?url= links work without a path ID.

Embed: fall back to demo replay when the match replay is not found in R2/B2
instead of showing "Failed to fetch" (handles test match IDs with no replay).

App: extend skeleton and PIP checks to match /watch/replay (with or without :id).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 13:07:13 -04:00
jedarden
ae0f072f80 feat(web): route R2 assets through Pages Function instead of r2.aicodebattle.com
The aicodebattle.com domain was never registered. Replace all hardcoded
https://r2.aicodebattle.com references with the /r2/ relative path, served
by a Cloudflare Pages Function that reads from the acb-data R2 bucket via
binding. Adds web/functions/r2/[[path]].ts and web/wrangler.toml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 07:55:44 -04:00
jedarden
cd30484e8c verify(blog): verify blog page generates and renders AI match commentary posts
Verification results:
1.  /data/blog/index.json exists and has 1 post (meta-week-13-season-1)
2.  Individual post pages load correctly at /blog/{slug}
3.  Blog post JSON structure matches frontend expectations (content_md field)
4.  Tags and filters implemented in UI (All, Meta Reports, Chronicles buttons)
5.  Blog page builds successfully (blog-D4QMd11d.js included in build)

Current state: Blog infrastructure is fully implemented with:
- LLM-powered narrative generation (blog.go, narrative.go)
- Story arc detection (rise, fall, rivalry, upset, evolution milestones)
- Weekly meta report generation with ELO movers, strategy analysis
- Chronicles for story arcs (rivalry, upset, rise/fall, evolution)
- Tag-based filtering and search

Note: Current blog content is placeholder/template-based. Meaningful
match commentary will be generated when:
- ACB_LLM_BASE_URL and ACB_LLM_API_KEY are configured in index-builder
- Real match data exists in PostgreSQL database
- Story arcs are detected from rating history and match results
2026-04-25 10:40:36 -04:00
jedarden
b1121ed6f8 feat(playlists): add playlist curation and rebuild logic per §10, with series/seasons/enrichment
Implement auto-curated playlists in the index builder: 12 playlist types
(closest finishes, upsets, comebacks, marathons, rivalry classics, etc.)
with weekly highlight curation. Add DB persistence, R2 pruning exemptions,
frontend pages, and AI commentary enrichment pipeline.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 16:11:27 -04:00
jedarden
91d807cec2 feat(web,cmd): enhance evolution dashboard, series/seasons pages, and matchmaker
- Evolution page: live polling (10s), activity feed, candidate tracking,
  statistics section, island overview with live.json schema
- Series page: detailed series view with game-by-game results
- Seasons page: season list with status and champion display
- Predictions page: enhanced prediction UI with open matches
- API types: add CycleInfo, Candidate, ActivityEntry, Totals for live.json
- Embed: improved embeddable replay widget
- Mobile CSS: responsive breakpoints and bottom tab bar
- Exporter: enhanced live.json generation with full cycle/candidate data
- Matchmaker: series scheduling support with config
- Worker: additional database queries for series/season data

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 13:42:20 -04:00
jedarden
804e31798f Add Phase 9 features: embeddable replay widget and playlists
Embeddable Replay Widget:
- web/embed.html: Minimal standalone HTML with Open Graph and Twitter Card tags
- web/src/embed.ts: TypeScript embed viewer with auto-play, progress bar, keyboard controls
- R2 warm cache + B2 cold archive fallback for replay loading
- ~7KB gzipped (well under 50KB target)

Replay Playlists:
- cmd/acb-indexer/src/playlists.ts: Auto-curated playlist generator
  - Featured, upsets, comebacks, domination, close games, long games, weekly categories
  - Uses match data to detect notable games
- web/src/pages/playlists.ts: SPA page for browsing playlists
- web/src/api-types.ts: Added playlist types and fetch functions

Other changes:
- web/src/replay-viewer.ts: Added getIsPlaying() method for embed viewer
- web/vite.config.ts: Added embed.html as build entry point
- web/app.html: Added Playlists nav link
- web/public/img/embed-placeholder.svg: OG image placeholder

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 02:03:45 -04:00