This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
What I Built
I keep re-checking the same web pages. A portal status. A deadline. A price. An announcements page. It takes two minutes each time and I forget half the time anyway.
SlothWatch is a lazy web-chore watcher. You tell it once, in plain English, what you care about on a page:
slothwatch add https://example.com/page --care "tell me if the deadline changes or results are announced"
After that:
A cloud browser (Browserbase, driven by Stagehand) opens the page on a schedule and pulls the text.
If the page is identical to last time, SlothWatch stops. No model call at all.
If something changed, a local Gemma model running on my laptop through Ollama reads only the change and decides if it matters to me.
If it matters, my phone gets a two-line push through ntfy. If not, silence.
Silence is the feature. A sloth does not check things twice.
Demo
Code
SlothWatch 🦥
Built during Hacktoberfest Open-Source AI Challenge Week 3 (Oct 19-25, 2026)
Note: This project was conceived, designed, and built entirely inside the challenge window.
Submission Deadline: October 25, 2026, 11:59 PM PDT (October 26, 12:29 PM IST).
Landing Page: slothwatch.tech (ordocs/on GitHub Pages)
SlothWatch is a lazy web-chore watcher. You describe in plain English what you care about on a web page. A cloud browser (Browserbase + Stagehand) visits the page on an automated schedule. Visible text is extracted deterministically and hashed. If the page is unchanged, SlothWatch exits immediately—consuming 0 LLM calls, 0 tokens, and 0 API dollars.
When real text changes occur, a local open-weight model (Gemma via Ollama) evaluates the compact diff to determine if it satisfies your intent. Your phone receives a push notification via ntfy only when it genuinely matters—filtering out timestamps, visitor counters, ads, and cookie…
Install:
npm install -g github:[[your-username/your-repo]]
slothwatch init
slothwatch doctor
You need Node 20+, Ollama with a pulled model, a Browserbase API key, and an ntfy topic.
How I Built It
Stack: TypeScript, Stagehand and Browserbase for browser sessions, Ollama running [[Gemma tag, for example gemma4:e2b]] for judgment, SQLite for state, ntfy for push. Built on a laptop with an RTX 2050 and about 15 GB RAM. No closed model API anywhere in the path.
The design rule that made it work: split the job. My first instinct was to let the model drive the browser. Small local models are not reliable at that. So the browser does the deterministic work (navigate, wait, extract text) and the model only reasons over plain text it is handed. [[One or two sentences from NOTES.md on what actually failed when you tried the other way, if you tried it. If you did not, delete this sentence.]]
Laziness, enforced in code:
Hash check first. Page text is normalized and hashed. Same hash as last run means no model call. [[X of Y runs skipped the model entirely, from stats.]]
Recipe replay. The first run of a watch can include steps like dismissing a banner or clicking a tab. Those steps are recorded, and later runs replay them without asking a model to rediscover anything. [[First run took X s with Y model calls, replay took X s with 0, from stats.]]
Strict judge output. Gemma must return JSON with matters, a two-line summary, and a reason, validated with zod. Invalid output is retried once, then recorded as a failed judgment. It is never silently treated as "nothing changed".
Read-only. It never submits forms, buys anything, or posts for you.
Benchmark. I wrote [[N]] labelled test cases (real changes, noise like timestamps and cookie banners, and a few tricky ones) and ran them through [[model names]]:
| Model | Accuracy | Score | False Positives (Noise) | False Negatives (Missed) | Invalid JSON / Retried | Avg Latency | Avg Tokens |
|---|---|---|---|---|---|---|---|
| gemma4:e2b | 95.5% | 21/22 | 1 | 0 | 0 / 0 | 5.31s | 696 |
| gemma4:e4b | 95.5% | 21/22 | 1 | 0 | 0 / 0 | 6.35s | 550 |
| llama3.2:3b | 90.9% | 20/22 | 2 | 0 | 0 / 0 | 1.81s | 527 |
Why Does Open Innovation Matter?
Private by default. Page content, including pages behind a login, is judged by a model on my own machine. It never goes to a closed API.
Costs nothing per check. After setup, each judgment is free. A closed API would turn "check this page every hour" into a bill that grows with every watch.
Swap the brain. The model is one config line. That is how the benchmark above was possible: same cases, different open models, real numbers.
Honest limits. Small open models were [[describe the real weakness from your benchmark]]. Splitting the job let me keep the model local anyway. A bigger closed model might have judged better, but it would have cost the privacy and the zero bill, which were the point.
My Agent Session
The Lazy Payoff
Prize Categories
Best Use of Browserbase: Stagehand sessions fetch and render pages, and recipes turn a one-off run into a repeatable workflow.
Best Use of Gemma: Gemma runs locally through Ollama as the judge and was benchmarked against other open models.
Top comments (0)