Files
teahubxyzandClaude Fable 5.1 1aeebac6f2 harness: a resume mode (autoplay blocked); docs for the state machine and hooks
tools/harness.sh resume seeds IndexedDB with a station and one rendered
track, resumes it with no user gesture and expects the TAP TO PLAY wait.
IndexedDB needs http, so the page is served from a temp folder; headless
Chrome's virtual time doesn't wait for IndexedDB, so this mode is driven in
real time over the DevTools protocol (tools/harness-cdp.py, stdlib only).
The loop harness now prints state.phase too.

ARCHITECTURE.md describes the machine as implemented; HANDOFF.md lists what
was found and left alone; STORAGE.md gains db.get and the tapes store (the
code already had both); README points at the new files.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K6897PWcUEwHiqZMcVnNF6
2026-10-21 06:01:48 +00:00

37 lines
2.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`, which only answers pages served
from `*.yolopreneur.lol` or `gandora.lol`. For local work either add a personal Venice key (open `/?key` to show the
key box) or test with `tools/harness.sh`, which stubs the backend. Everything the listener makes lives in their
browser (IndexedDB) — see STORAGE.md.
## Files
- `index.html` — the whole app: markup, styles, and the player (a small state machine), station, library, tapes,
breaks, covers, sheets, and the `hooks` brain.js plugs into.
- `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 by `tools/icons.py` (stdlib only).
- `tools/shots.sh` — the card image and the icons, run by `.gitea/workflows/shots.yml` on every push.
- `tools/harness.sh` + `tools/harness.html` (the station loop) + `tools/harness-resume.html` and `tools/harness-cdp.py`
(resume with autoplay blocked) — the playback regression harness (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.