Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K6897PWcUEwHiqZMcVnNF6
2.0 KiB
g*ndora
A radio station that writes its own songs. Type a seed, get a station: a DJ (an LLM) writes each track's sheet music (title, tags, lyrics, bpm, key, length, meter, a line to say), a song model (ACE-Step) renders it, the cover is drawn from the song's own settings, and every reaction you make teaches a small taste model that steers the DJ.
Live at https://gandora.lol (also gandora.yolopreneur.lol). Installable as a PWA; the library plays offline.
Run it
It is one static page. Serve the folder and open it:
python3 -m http.server 8794 && open http://127.0.0.1:8794/
It talks to the factory's inference worker at https://inference.yolopreneur.lol (allowed origins include
localhost? no: only *.yolopreneur.lol and gandora.lol; for local work add your Venice key with /?key or run
from a *.yolopreneur.lol host). Everything the listener makes lives in their browser (IndexedDB) — see STORAGE.md.
Files
index.html— the whole app: markup, styles, and the player, station, library, tapes, breaks, covers, sheets.brain.js— the taste model (a small net per station and overall), the TASTE screen, the DJ's taste text.sw.js— service worker: caches the shell; stamped with the commit by the shots workflow.manifest.json,icons/,favicon.svg— PWA. Icons are drawn bytools/icons.py(stdlib only).tools/shots.sh— the card image and the icons, run by.gitea/workflows/shots.ymlon every push.tools/harness.html— the playback regression harness (see ARCHITECTURE.md › Testing).STORAGE.md— the IndexedDB contract.ARCHITECTURE.md— how it all fits.HANDOFF.md— read before changing things.
Backend
The page never holds a key. inference.yolopreneur.lol (teahubxyz/time, .github/time/cloudflare/inference.js)
routes per capability: chat → Venice (claude-haiku), render → Runware ACE-Step (Venice as fallback), speech → Venice
TTS. Secrets and deploys: .github/time/SECRETS.md in that repo.