TimeLeak is deliberately boring engineering: a watcher, a folder, some counting, one API call a day. Here is exactly what happens and what does — and doesn't — touch the network.
Every 5 seconds it appends one JSON line — active app, window title, idle seconds — to
~/TimeLeak/logs/YYYY-MM-DD/meta.jsonl, and saves one downscaled JPEG unless
you're idle or the window title matches your redaction list (then: no screenshot, title
logged as [redacted]). A day is ~8,640 lines and 100–200MB of frames.
Folders older than 7 days are deleted automatically. Network calls made by the
watcher: zero.
timeleak.py stats computes minutes-per-app, context switches per hour,
polling loops (a context visited 5+ times with dwell under 90s), and your longest focus
blocks. Pure Python counters. Network calls: zero.
analyze.py compresses the day into a ~2,000-token digest of aggregates and
sends it — with your own API key — to a small model (Claude Haiku class, ~1–3¢/day). Pass
--vision and up to 20 sampled frames go along for the stretches text can't
explain. The model returns observations: behavior, evidence, estimated minutes,
concrete fix.
Each observation lands in ~/TimeLeak/ledger.json under a stable slug with
a day counter. Seen once: noted. Twice: watching. Three separate days: confirmed —
and only confirmed leaks make the fix-list. This is what keeps the briefs calm and real.
Every confirmed leak ships with its mechanism: the hotkey to bind, the digest script to schedule, the extension to install, the tool swap to make. Apply once; verify next week in your own data that the minutes actually came back.
| Data | When | Where |
|---|---|---|
| Nothing | watcher + stats (free tier) | — |
| Text digest of aggregates | Pro brief, when you run it | the model API you configured |
| Up to 20 downscaled frames | only with --vision | same, your key |