n. a morning song; a poem or lyric about lovers parting at dawn.
A three-minute voice-narrated morning radio broadcast about your life.
Your overnight commits. Your cold projects. Yesterday's broken promise. Today's one thing. Read aloud by a voice that isn't trying to sell you anything. Thirty seconds of setup, three minutes of listening, ninety minutes of focused work. That's the whole contract.
npx aubade"It's Tuesday, April sixteenth, and the sun came up at six fifty-three. You pushed four commits to Audrey last night โ the memory reconsolidation pass is in. Three projects are cold, but genesis-prism blinked last Thursday, so it's not dead. One thing to do today, and only one: finish the landing page. Ninety minutes. Coffee. Go."
โถ Listen to the sample ยท Visit the landing page
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ W โ AUB 88.3 FM โ ON AIR โ
โ โ
โ โผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ โ โ โ โ โ โ
โ โ
โ Thursday, April 16th mood: clear ))) ) โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
"Every morning I wake and the world is a rumor."
โ after Jack Gilbert
โบ Four commits to audrey last night. The reconsolidation pass is in.
Termivibe hasn't moved in fourteen days. That's not death. That's
shelved. Yesterday's thing was the landing page. You didn't finish
it. Here it is again.
The world is not asking for seventeen things today. The world is
asking for one. You know which one.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ The one thing: Finish the landing page. Ninety minutes. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
space: play ยท r: replay ยท q: quit
I have sixty-something project folders across two drives. Most half-finished. Some genuinely good. All of them compete for attention every morning. A Notion page doesn't help. A todo app doesn't help. What helps, a little, is a patient voice that says you wrote four commits to audrey last night, the landing page is still undone, that's the thing for the next ninety minutes.
Aubade is that voice.
OPENAI_API_KEY=sk-... npx aubadenpm install -g aubade
aubadegit clone https://github.com/evilander/aubade.git
cd aubade
npm install
cp .env.example .env # add your keys
node bin/aubade.js --dry-run # verify install; no API callsAubade needs one LLM key. Everything else is optional.
# --- LLM (required, pick one) ---
ANTHROPIC_API_KEY=sk-ant-... # preferred โ follows the style rubric
# OPENAI_API_KEY=sk-... # fallback โ works, but prosier
# --- Text-to-speech ---
AUBADE_TTS=openai # or "kokoro" for local/offline
AUBADE_VOICE=nova # any OpenAI voice
# --- Signal scanning ---
AUBADE_ROOTS=B:/projects,A:/ai # comma-separated roots to scan
AUBADE_AUTHOR=you@example.com # filter commits by author
# --- Script shape ---
AUBADE_DURATION_SECONDS=180 # ~3 minutes
AUBADE_OPERATOR=Tyler # your name, used at most once
AUBADE_LAT=39.9 # for sunrise (default: Quincy, IL)
AUBADE_LON=-91.4
# --- Storage ---
AUBADE_HOME= # default: ~/.aubade| Command | What it does |
|---|---|
aubade |
Generate + synthesize + play today's aubade. Renders the Ink TUI. |
aubade --text-only |
Generate the script only. No audio. |
aubade --dry-run |
Canned sample. No API calls. Useful for verifying install. |
aubade --plain |
Print to stdout without the TUI (good for cron / CI / pipes). |
aubade --recent 7 |
List the last seven broadcasts. |
30 6 * * 1-5 /usr/local/bin/aubade --plain > ~/.aubade/log 2>&1$action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c npx aubade"
$trigger = New-ScheduledTaskTrigger -Daily -At 6:30am
Register-ScheduledTask -TaskName "Aubade" -Action $action -Trigger $triggerEvery broadcast follows the same three-beat structure:
- An opening observation โ never a greeting, always specific. A line you didn't expect from a morning app.
- Two or three short paragraphs โ one signal is the spine, the others are texture. No roll-call of every repo.
- One commitment โ verb first, concrete, time-boxed to ninety minutes.
The voice is Marilynne Robinson in Gilead, trimmed. A literary touch is allowed โ one image, one motif โ but never flowery.
โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ aggregators/ โ โ script/ โ โ tts/ โ
โ git โ โ โ prompt.js โ โ โ openai.js โ
โ projects โ โ generate.js โ โ kokoro.js โ
โ notes โ โ rubric.js โโโโ โ โ โ
โ clock โ โ (regen loop)โ โ โโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โ
โ โ โผ
โ โ โโโโโโโโโโโโโโโโ
โ โผ โ ~/.aubade/ โ
โ โโโโโโโโโโโโโโโโโโโโ โ audio/*.mp3 โ
โโโโโโโโโโโโ memory/ โ โโโโโโโโโโโโโโโโ
โ aubade.db โ โ
โ (sqlite) โ โผ
โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ โ play/audio.js โ
โผ โ (cross-platform) โ
yesterday becomes โโโโโโโโโโโโโโโโโโโโ
context for today
LLMs write flowery prose if you let them. Aubade doesn't ask nicely โ it validates. After the model returns a script, src/script/rubric.js checks:
- No banned phrases โ dormant, foyer, ripple, whispers, canvas, tether, pristine, and a growing blacklist
- Sentence length โ average โค 12 words
- Adjective density โ โค 10% of words
- Commitment grammar โ must start with a concrete verb and name a time box
- No roll-call โ more than one "N files changed" sentence = reject
If the rubric fails, the generator regenerates up to 3 times, feeding the failure notes back into the next prompt.
npm test21 tests passing across clock / git / projects / prompt / rubric / store:
โ test/clock.test.js (4 tests)
โ test/prompt.test.js (5 tests)
โ test/projects.test.js (3 tests)
โ test/rubric.test.js (6 tests)
โ test/store.test.js (3 tests)
aubade/
โโโ bin/aubade.js # CLI entry
โโโ src/
โ โโโ index.js # orchestration
โ โโโ aggregators/ # collect signals from your world
โ โโโ script/ # prompt + LLM + rubric
โ โโโ tts/ # OpenAI + Kokoro providers
โ โโโ memory/ # SQLite store
โ โโโ play/ # cross-platform audio playback
โ โโโ cli/ # Ink TUI (no build step)
โโโ test/ # vitest, 21 tests
โโโ landing/ # single-file marketing page + sample.mp3
โโโ CLAUDE.md # vision & principles
โโโ codex.md # full handoff doc
โโโ README.md # this file
-
npm publishunder theaubadename - Deploy landing page to
aubade.dev - Feedback loops โ verify commitment completion by checking target repo for commits at T+90;
--rateflag - Audrey integration โ replace local SQLite with Audrey biological memory
- Streaming TTS for faster time-to-first-audio
- Weekly digest โ longer-form Monday broadcast summarizing the past seven days
- Team mode โ aggregate across multiple authors for engineering managers
See codex.md for the full technical handoff and open tasks.
- Audio-first. Start your day with headphones in and eyes closed. The terminal UI is decorative.
- Local-first. Your git logs and project folders never leave your machine. Only a short prompt goes to the LLM.
- Literary voice. No "Good morning, Tyler!" No "Here are your 7 priorities." No emojis. The opening line is an observation, not a salutation.
- Memory is structural. Yesterday's broadcast is context for today's. Over a week, patterns emerge.
- Ships as a real artifact.
npx aubadeworks on day one. No build step. No Docker. No backend.
Built as part of the Genesis superskill run on 2026-04-16 in Quincy, Illinois. Uses Ink for the TUI, suncalc for dawn math, kokoro-js for local voice synthesis, and the epigraph canon of anyone from Thoreau to Wordsworth to Marcus Aurelius.
MIT โ Tyler Eveland, 2026.
โ Eveland Digital, 2026