__
____ __ ______/ /___ ______
/ __ \/ / / / __ / __ `/ ___/
/ / / / /_/ / /_/ / /_/ / /
/_/ /_/\__,_/\__,_/\__, /_/
/____/
psst — your audit is in 5 days.
local. quiet. on time.
Local-first task scheduling, calendar sync, and unattended Claude Code session launch.
Claude Code's /schedule is a great idea, but in practice the cloud-hosted remote-agent model rarely beats a fine-grained local one. If you're already maxxing your local sessions, running Tailscale (or similar) so your dev environment is reachable, and have your real work on disk and in local git — you don't need a sandboxed remote checkout to fire off a reminder or run a scheduled task.
nudgr runs entirely locally:
- SQLite as the source of truth at
~/.local/share/nudgr/db.sqlite - Three calendar paths, no auth setup required: native EventKit push-sync on macOS (TCC permission only, no OAuth), zero-auth handoff via pre-filled Google Calendar URL on any platform (the
askdefault surfaces a 3-button macOS dialog after every add), or a Google Calendar API backend if you want full lifecycle sync to Google specifically - A SessionStart hook so Claude knows what's coming up the moment you open a session, and brings it up conversationally
- Optional unattended Claude sessions scheduled in tmux: write a prompt MD, set a time, nudgr fires it via launchd/systemd at the scheduled moment, captures logs, archives the run in history
- Catch-up on missed runs: if your laptop was asleep, nudgr surfaces the missed items on next session — auto-runs (if you said
--on-miss run_now), or asks you to confirm
Your stuff, your machine, your calendar.
nudgr /schedule
_o_ *PUSH* _o_ ☁
| | | ────► | | | ─ ─ ─ ─ ─ ─►
/ \ / \ ╲
───────────────────────────╲ ╲
╲___ ╲
local-first ╲___ ╲___
cache-warm ╲___ ╲___
on-disk ╲___ ╲___
in-tmux ╲___ ╲ ☁ "cold start"
╲___
╲___ 💸
Pre-1.0. APIs and schema may change between minor versions until we cut 1.0.0. See CHANGELOG.md.
bash <(curl -fsSL https://raw.githubusercontent.com/Bobby-Gray/nudgr/main/scripts/install.sh)The script is idempotent (safe to re-run), detects your OS, installs prerequisites (uv, tmux, optionally terminal-notifier), then runs nudgr init + install-skill + install-dispatcher, and finishes with a nudgr doctor report. Read it first if you don't trust pipe-to-bash:
scripts/install.sh.
Requires uv and Python 3.11+. System prerequisites: tmux (required for scheduled Claude sessions), claude CLI (required to actually fire scheduled sessions — install + auth from https://docs.claude.com/en/docs/claude-code).
# macOS
brew install tmux terminal-notifier
# Linux (Debian/Ubuntu)
sudo apt-get install -y tmux libnotify-bin
# All platforms
uv tool install --from git+https://github.com/Bobby-Gray/nudgr.git nudgr
nudgr init # create DB + config
nudgr install-skill # link the SKILL.md into ~/.claude/skills/
nudgr install-dispatcher # launchd/systemd timer for scheduled sessions
nudgr doctor # confirm everything's wiredOn macOS, you'll be prompted twice for permissions on first use:
- Calendar (one-time):
nudgr sync --grant - Automation (Terminal/iTerm): primed during
nudgr install-dispatcher. If you missed it or denied, re-runinstall-dispatcherto surface the prompt again.
Native Windows isn't supported (no tmux, no launchd/systemd). Use WSL2 + Ubuntu, then follow the Linux instructions above. The Windows-host's notification center won't receive nudgr's banners by default; WSLg or a desktop notification bridge is needed.
| Path | Setup | Behavior | Best for |
|---|---|---|---|
| EventKit (macOS) | nudgr sync --grant once |
Full lifecycle push-sync — items get mirrored to a nudgr calendar in Calendar.app, kept in sync on edits / cancels / completions |
Mac users who want the whole backlog visible |
| URL handoff (any browser) | None | After each nudgr add / nudgr schedule, a 3-button macOS dialog asks: Add to Google Calendar? / Skip this one / Don't ask again. "Add" opens your already-authed Google Calendar with the event prefilled — you click Save |
Anyone, especially cross-device or iCloud users |
| Google API | OAuth setup (nudgr auth google + a GCP Desktop OAuth client) |
Full lifecycle push-sync to Google Calendar | Power users who want the whole backlog mirrored to Google specifically |
The handoff path is on by default (calendar.handoff = ask) and works alongside whichever push-sync backend you've configured. To turn it off: pick Don't ask again in the dialog, or run nudgr config set calendar.handoff never. To always auto-open without asking: nudgr config set calendar.handoff always.
# casual reminders
nudgr add "review the audit doc" --due "tomorrow 9am" --project work
# what's pending
nudgr upcoming --days 14
# schedule an unattended Claude session
nudgr schedule "weekly dependency audit" \
--at 2026-06-14T09:00 \
--working-dir ~/projects/my-app \
--mode autonomous
# inspect history
nudgr history --since "3 weeks ago"
# attach to a running session
nudgr sessions attach 42A SQLite database holds every item (reminder, calendar event, task, or scheduled Claude session). A small CLI mutates it. A platform-specific timer (launchd on macOS, systemd user-units on Linux) calls nudgr dispatch every minute, which scans for due claude_session items and launches them in detached tmux. After every mutating CLI call (or on explicit nudgr sync), a calendar backend pushes the current state to your Calendar.app or Google Calendar — push-only, never pulls. The default Google path is a one-shot URL handoff (no OAuth), surfaced via a native macOS dialog after each add. A Claude Code SessionStart hook calls nudgr upcoming --format claude-prompt so the assistant knows what's coming up and what was completed since you last opened a session.
src/nudgr/ CLI + DB + sync + dispatcher
cli.py Typer-based entry points
db.py SQLite schema + connection helpers
models.py Pydantic types for items, dispatches, calendars
config.py config.toml load/save
paths.py XDG-compliant path resolution
dispatcher.py The timer-driven Claude-session launcher
recurrence.py RFC 5545 RRULE expansion via python-dateutil
render.py Output formatters (table, json, claude-prompt)
tmux.py Detached session launch + attach helpers
notify.py Cross-platform desktop notifications
calendars/ Calendar backends (eventkit, google, caldav)
host/ launchd / systemd unit generators
auth/ OAuth flows
skill/ The Claude skill that ships from this repo
SKILL.md
docs/
tests/
Issues and PRs welcome. The project is pre-1.0 and APIs may change between minor versions — see CHANGELOG.md for the release arc and CONTRIBUTING.md for branch / commit / test conventions.
This is a personal tool that I'm sharing because the local-first /schedule replacement felt useful. Not monetized, not seeking growth-at-all-costs — just a small thing that does its job.
MIT — see LICENSE.
┌──────────────────────────────────────────────┐
│ ⌐■_■ "you said you'd do this on Tuesday." │
└──────────────────────────────────────────────┘
nudgr