3 roles, 4 files, no build tools.
index.html ← Config, state, DOM, TTS, crowd detection, event wiring
js/llm.js ← LLM framework (shared — don't break it)
js/ghosts.js ← Ghost generation (Dev 2's zone)
js/show.js ← Show runner, judging, Boo MC, OVERDRIVE (James's zone)
CLAUDE.md ← Agent instructions (read this if using Claude Code)
HANDOFF.md ← Architecture + work split + secrets
CONTRIBUTING.md ← This file
Your file: js/ghosts.js
What to do:
- Edit
GHOST_PROMPTto make ghost generation prompts more creative - Add MORE models to
CONFIG.featherless.models.corpusinindex.html—llmFanOuthits all of them in parallel (12,000+ available at featherless.ai/models) - Make the pitch card visually pop when a ghost presents (edit CSS in
index.html) - After generation, index pitches into Needle (see HANDOFF.md)
- Keep
FAILSAFE_GHOST("Der Speisekarten-Geist") as the last ghost
Don't touch:
js/show.js— judging, Boo, crowd, OVERDRIVEjs/llm.js— LLM framework (use it, don't change it without asking)
Test your changes:
git push origin main
open https://hackathon-berlin-mar-2026.westover.lolYou edit CONFIG.judges in index.html — the backstory strings.
Each judge has:
{
key: 'carla', // don't change
name: 'Karla von Strategos', // ghost name (can edit)
voiceIdx: 2, // don't change
backstory: 'You are the ghost of Carla Schneider. In life...', // EDIT THIS
}Guidelines for backstories:
- Start with "You are the ghost of [Real Name]."
- Include how they died (funny/dramatic)
- Include what they judge (business viability, technical depth, product craft)
- Include a catchphrase
- Keep under 200 words — these go into LLM prompts
Also edit:
BOO.backstoryinjs/show.js— the MC ghost's personality- Ghost names in
CONFIG.judges[].name— make them spooky/funny
My file: js/show.js
My zone:
judgeGhost()— judge deliberation with Boo + core + chaos judgesbooJudge(),booSpeak(),summonChaosJudges()decideBuild()— BUILD/NO BUILD via Boooverdrive()— build + deploy pipelinerunShow()— main flow orchestration- Needle integration for judge RAG context
Also own in index.html:
listenToCrowd()— Web Audio FFT crowd detection- Crowd detection config (
CONFIG.crowd)
| Key | What | Who edits |
|---|---|---|
featherless.apiKey |
API key (expires 2026-03-17) | nobody |
featherless.models.corpus |
Models for ghost generation | Dev 2 |
featherless.models.judges |
Models for judge LLM calls | James |
needle.apiKey |
Needle RAG API key | nobody |
crowd.* |
FFT detection params | James |
tts.* |
Speech rate/pitch defaults | anyone |
judges[] |
Judge personas + backstories | Business |
- Don't break the flow — the show runs top to bottom in
runShow() - Keep it fast — 2.5 minutes total for the presentation
- TTS rate >= 1.1 — ghosts talk fast
- Judge verdicts = 1 sentence —
maxTokens: 60 - Test at the live URL — local
file://won't work (needs HTTPS for mic) - Use the LLM framework — never call
fetch()to Featherless directly, usellmCall/llmJSON/llmFanOut/llmStream