thrown tomatos => throwntom
CLI-first pomodoro timer that won't let you forget to start timers, with repeating reminders until explicit confirmation.
go build -o throwntom ./cmd/throwntomgo install github.com/jwp23/throwntom/v3/cmd/throwntom@latestthrowntom
throwntom --config path/to/config.tomlType these commands in the interactive prompt:
start- start work periodnew-cycle- start a fresh cycle now (reset cycle progress, keep today's total)pause- pause the active pomodoro or break timerresume- resume a paused pomodoro or break timerstop- stop active timer and return to idleconfirm- acknowledge transition and start next phasesnooze <duration>- snooze current reminder (example:snooze 10m)skip-today- stop reminders for the current daystats- show productivity dashboard (today, week, month, all-time, streaks, patterns)status- print current statustest-sound- play the reminder sound immediately to verify terminal audio/bellquit- exit throwntomexit- alias forquit
Manage focused tasks for your pomodoro sessions. Tasks are persisted to ~/.config/throwntom/tasks.json.
task add <desc>- add a new tasktask done <n>- mark task numbernas completedtask remove <n>- delete task numberntask list- show active taskstask completed- show completed taskstask clear- clear completed taskstask focus <n>- focus on tasknduring a work sessiontask unfocus <n>- remove focus from task at positionntask up <n>- move focused task up in prioritytask down <n>- move focused task down in priority
When starting a pomodoro or confirming a transition to work, you'll be prompted to select which tasks to focus on for that session.
throwntom automatically saves session state to ~/.config/throwntom/session.json after every command and on shutdown. When you restart, it restores:
- Timer position (adjusted for wall-clock time elapsed while closed)
- Engine state (work, break, paused, awaiting confirmation)
- Completed pomodoro counts for the day
- Focused task selections
If the saved session is from a different day, it is discarded and throwntom starts fresh. If the timer expired while closed, it transitions to awaiting confirmation. Paused timers remain paused with their remaining duration preserved.
throwntom records every meaningful event (pomodoro start/complete, breaks, pauses, snoozes) to ~/.config/throwntom/events.jsonl. This append-only log powers the stats command, which displays:
- Today / This Week / This Month / All Time — pomodoro counts, focus time, pauses, snoozes
- Streaks — current and longest consecutive days with at least one pomodoro
- Patterns — best day of the week, most productive hour, snooze/pause rates
Pomodoro counts are color-coded by tier (configurable):
| Tier | Default range | Color |
|---|---|---|
| Cool | 0–2 | gray |
| Warm | 3–5 | amber |
| Hot | 6+ | green |
Config file location: ~/.config/throwntom/config.toml
Example config.toml:
[pomodoro]
work_minutes = 25
short_break_minutes = 5
long_break_minutes = 15
long_break_every = 4
# days omitted → defaults to weekday (Mon-Fri)
[[schedule]]
time = "09:15"
# specific-day override carves out from the default group
[[schedule]]
days = ["Fri"]
time = "10:00"
repeat_secs = 20
sound_command = ["paplay", "/usr/share/sounds/freedesktop/stereo/bell.oga"]
morning_reminder_pending = true
emoji = true
[stats]
tier_low = 2
tier_mid = 5Schedule supports day aliases: "weekday" expands to Mon-Fri, "weekend" to Sat-Sun. Specific-day entries automatically carve out from alias expansions.
go test -timeout 30s ./... -v
go vet ./...
go build ./cmd/throwntomInstall local git hooks:
./scripts/install-git-hooks.shCommit-time checks in .githooks/pre-commit run:
gofmtverification (gofmt -l .)- fast tests (
go test -timeout 30s ./...)
Heavier checks intentionally kept out of pre-commit and run in CI:
- lint + complexity gate (
golangci-lint run ./...) - integration tests (
go test -timeout 30s -tags=integration ./integration) - e2e tests (
go test -timeout 30s -tags=e2e ./e2e) - security scan (
govulncheck)
- On macOS, notifier uses
afplaywith system soundGlass.aiff. - On Linux, notifier first tries
sound_command(if configured), thenpaplay,canberra-gtk-play,aplay, and finally terminal bell (\a). sound_commandis optional and must be a TOML string array where the first item is the executable, and remaining items are args.