Sloth FM

Your GitHub inbox, read overnight by a sloth on your own laptop.

While you sleep, Gemma 3 works through your GitHub notifications one at a time, right on your machine. In the morning an open-weight voice reads you a short radio show and leaves a page of links. No API keys, no cloud, no cost.

On air

Listen to this morning's show

A real episode, made from my own notifications on my own laptop. The voice is Kokoro, an open-weight model, running locally.

Sloth FM, morning edition

What needs you today, what is yours this week, the good news, and how much noise was cleared away. Private repositories and security advisories are left off the air.

Transcript

Good morning. This is Sloth FM. While you slept, I read 76 GitHub notifications, slowly, on your own laptop, so you would not have to.
5 things need you today.
First: You need to address the bug report regarding instrumentation spans leaking in the opentelemetry-go-compile-instrumentation repo.
Next: You need to address a bug in the opentelemetry-go-compile-instrumentation repo regarding span leaks.
Then: In opentelemetry-go-compile-instrumentation, you need to review and respond to this naming request.
Also: You need to address the review request on the opentelemetry-go-compile-instrumentation repo.
And: You need to review the draft issue for the opentelemetry-go-compile-instrumentation repo, you've been asked for feedback.
13 more are yours this week, but nobody is blocked on them. They are on your morning page.
Some good news: 9 things went well.
In opentelemetry-operator, your pull request was merged.
In opentelemetry-go-compile-instrumentation, your pull request was merged.
The other 49 were noise: 28 CI runs that need nothing from you, 16 threads you were only following, 5 releases from repositories you watch. You can ignore them.
Rest is not wasted time; it’s the quiet foundation for a deliberate life.
That is all. Go back to sleep for five more minutes. You have earned it.

How it works

Code does the sure things. Gemma does the thinking.

The model only sees what a person would have to think about, and it never writes a number. A Temporal workflow holds the whole night together, so nothing is lost if the laptop sleeps.

Temporal workflow: NightShift
  1. gh notifications

    Your recent GitHub notifications, fetched with the GitHub CLI you already use.

    input
  2. SQLite journal

    Every thread is written down first, so the night always knows where it got to.

    on disk
  3. Code decides the obvious

    Passed CI, releases you only watch, merged PRs, older runs on the same branch, PRs waiting on maintainers.

    code
  4. Gemma 3 judges the rest

    Needs you today, yours this week, good news, or noise. A reason and one spoken sentence each.

    local model
  5. Code writes the numbers

    Every count in the show comes from the journal, so nothing is ever made up.

    code
  6. Kokoro reads the show

    A short radio show and a morning page with a link for everything.

    local voice
  • One activity per notification, with retries
  • A durable timer that waits for the charger
  • A wake signal to start anyway
  • A progress query to check in

Slow on purpose

It takes its time, so you don't have to.

There is no rush overnight. Sloth FM is built to be gentle on your laptop and impossible to knock off course.

Waits for the charger

On battery it sets a durable timer and checks again every fifteen minutes. Plug in and it starts. Send wake if you want it to go now.

Rests between notifications

A short pause after each one keeps the fans quiet and the laptop cool while you sleep.

Resumes after a crash

Close the lid or kill the process. Temporal remembers, and the night carries on from the next notification.

Decided by code first

Plain rules settle the sure things before the model is asked. Gemma only spends time where a person would have to think.

Private by default

Nothing leaves your laptop.

Your notifications are read by a model on your own machine and spoken by a voice on your own machine. There is no account to make and nothing to pay for.

  • API keys
  • Cloud models
  • Telemetry
  • Monthly bill
  • Security advisories stay off the airThe show says one is waiting for you, and keeps the details to itself.
  • Private repositories are never read aloudThey appear on your own morning page, and are redacted when you build it with --public.
  • Only GitHub is contactedThrough the gh CLI you already signed in to. Gemma, Kokoro and Temporal all run locally.
  • One optional actionAdd --tidy and it marks the noise as read on GitHub. That is all it ever does on your behalf.

Open models

Open weights, open licences.

Every part you need is free to download and runs on an ordinary laptop.

PartModelLicenceRuns
Judgement Gemma 3 4Bgemma3:4b Gemma Terms of Use Locally, through Ollama
Voice Kokoro 82Mbm_george Apache-2.0 Locally, through kokoro-onnx
Durability Temporal MIT Locally, temporal server start-dev

Run it

Set it up once, then go to bed.

$ python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
$ ollama pull gemma3:4b
$ scripts/sloth.sh            # starts Ollama and Temporal if needed, then waits for the charger
$ scripts/sloth.sh --now      # or start right away
$ .venv/bin/python -m slothfm progress   # how far did it get?
$ .venv/bin/python -m slothfm wake       # on battery, but start anyway
$ .venv/bin/python -m slothfm morning    # rebuild this morning's page and show
$ open ~/.slothfm/mornings/$(date +%F)/index.html

You will need macOS or Linux, Python 3.12 or newer, Ollama, the Temporal CLI, the GitHub CLI signed in with gh auth login, ffmpeg, and the Kokoro model files (kokoro-v1.0.onnx and voices-v1.0.bin) in ~/.slothfm/kokoro.

Add --tidy to mark the noise as read on GitHub.

Numbers from my own inbox

One real night.

Counted by code from the journal, not by the model.

notifications read
76
decided by code
57
judged by Gemma
19
minutes of night shift
2.3
length of the show
100 s
words in the show
1,255

Seen in Temporal

A night that knows how to wait.

The Temporal web UI showing the NightShift workflow night-2026-10-25 as running. Its timeline shows the collect and plugged_in activities, followed by a 15 minute timer waiting for the laptop to be plugged in
The night shift waiting for the charger, in the Temporal UI