BikeControl (SwiftControl)
Use Zwift Click, Zwift Play, Shimano Di2, or any Bluetooth controller with MyWhoosh, Rouvy, Zwift, and more. Free to try on iOS, Android, Windows, and macOS.
翻訳待ち
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Wait, what just happened? Point your phone at the TV and Laurel tells you.
Laurel is a second-screen companion for the Olympic and Paralympic Games. It captures a frame from the broadcast (camera, screen share, or upload), identifies the sport with Gemini Vision, retrieves the relevant rule context from a curated knowledge base, and streams a grounded explanation in seconds.
Built for the Team USA × Google Cloud Hackathon under the Choose Your Own Challenge track.
Prefer the original recording? Download the MP4.
| Stage | Hackathon MVP, deployed |
| Live frontend | https://laurel-dawsonpars-projects.vercel.app |
| Live backend | https://laurel-backend-926378227102.us-central1.run.app |
| License | Apache 2.0 |
| Sport coverage | 6 sports (3 Olympic, 3 Paralympic) |
| Last reviewed | 2026-05-11 |
| Route | What you see |
|---|---|
/ | Landing |
/demo | Both demo scenarios |
/demo/a | Curling double-touch call (auto-runs Gemini, suggests "What is the double touch rule?") |
/demo/b | Long jump T64 world record (auto-runs Gemini, suggests "What world record was broken?", "How does it compare to the regular Olympics?", "Why does it matter?") |
/sports | Browse the curated knowledge base |
/capture | Capture a moment yourself (camera, screen share, or upload) |
Works on phone and desktop. The demo routes pre-load broadcast mockups Laurel produced from scratch (no Games footage).
| Scenario | Trigger | What Laurel does |
|---|---|---|
| A — Confused viewer | A judge ruling negates a highlight in front of friends | Captures the frame, identifies the sport, cites the specific rule, explains the typical remedy. Under 5 seconds. |
| B — "Was that a big deal?" | A world record falls | Captures the frame, surfaces historical context and prior records, generates a sharable link with rich preview for the family group chat. |
| Layer | Technology |
|---|---|
| Frontend | Next.js 16, React 19, TypeScript, Tailwind 4 |
| Frontend hosting | Vercel |
| Backend | Python 3.12, FastAPI, uv |
| Backend hosting | Google Cloud Run |
| AI vision + synthesis | Gemini 2.5 Flash via Vertex AI |
| AI embeddings | text-embedding-005 |
| Persistence | Cloud Storage (frames) + Firestore (metadata) |
| Voice input | Browser-native Web Speech API |
| Streaming | Server-Sent Events |
Architecture diagram and the rationale behind each piece: docs/decisions/adr-0001-project-structure-and-stack.md.
Full feature catalog with file locations and rationale: docs/features.md.
| Surface | Highlights |
|---|---|
| Capture | Screen share (laptop), camera (phone), upload fallback, auto-mode detection, browser support probing, recording feedback ring |
| Vision | Multi-frame Gemini Vision identification, structured-JSON output, scenario-aware stub for offline dev |
| Knowledge base | Six hand-authored markdown files, section chunking, in-memory vector index over text-embedding-005 |
| Synthesis | SSE streaming, compliance-locked system prompt (no athlete names, conditional phrasing), scenario-routed stub |
| Conversation | Suggested chips, free-form input, voice input, 16px-no-iOS-zoom, persistent history |
| Sharing | Generate-link, native share sheet, OpenGraph rich previews, Cloud Storage persistence |
| Sport browser | Index page + per-sport accordion with full Markdown rendering |
| Demos | /demo index, /demo/a and /demo/b pre-loaded scenarios, replay-this-scene CTA |
| Visual identity | Animated laurel mark, intro animation, shimmer CTAs, processing pulse ring, prefers-reduced-motion respect |
| Compliance | Athlete-name lockout, NGB-name scrubbed KB, prescribed Games terminology, no non-Google corporate brands |
| Operational | Stateless backend, Cloud Build pipeline, CORS allowlist, stub-vs-Vertex client switch |
This is the beginning of the README. Read the rest at the original. Read the full README ↗