Skip to content

Bobby-Gray/nudgr

Repository files navigation

nudgr

nudgr — a stick figure pushing /schedule (a cloud) off a cliff, with motion lines

                    __
   ____  __  ______/ /___ ______
  / __ \/ / / / __  / __ `/ ___/
 / / / / /_/ / /_/ / /_/ / /
/_/ /_/\__,_/\__,_/\__, /_/
                  /____/

         psst — your audit is in 5 days.
         local. quiet. on time.

Local-first task scheduling, calendar sync, and unattended Claude Code session launch.

Why this exists

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 ask default 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"
                                                       ╲___
                                                           ╲___ 💸

Status

Pre-1.0. APIs and schema may change between minor versions until we cut 1.0.0. See CHANGELOG.md.

Install

One-liner (macOS / Linux / WSL2)

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.

Manual

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 wired

On 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-run install-dispatcher to surface the prompt again.

Windows

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.

Pick a calendar path

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.

Quickstart

# 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 42

Architecture (one paragraph)

A 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.

Layout

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/

Contributing

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.

License

MIT — see LICENSE.


       ┌──────────────────────────────────────────────┐
       │  ⌐■_■   "you said you'd do this on Tuesday." │
       └──────────────────────────────────────────────┘
                            nudgr

About

Local-first task scheduling, calendar sync, and unattended Claude Code session launch.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors