Skip to main content

Cap-aware tmux scheduler & auto-resume for Claude Code — schedule prompts and keep sessions running through the 5-hour usage limit.

Project description

⏻ claudekeeper

Schedule prompts for Claude Code, and keep your sessions running through the 5‑hour usage cap.

CI License: MIT Python Platform Dependencies

claudekeeper demo

claudekeeper is a tiny background daemon that watches your Claude Code sessions running in tmux and does two things your usage limit won't let you do on your own:

  • ⏰ Schedule — pre‑type a prompt in a pane and have claudekeeper press Enter at a wall‑clock time (2am, now + 30min, …). Kick off long runs while you sleep.
  • ♻️ Auto‑resume — when a session hits the 5‑hour usage cap, claudekeeper waits out the reset and continues it automatically, so work doesn't stall while you're away.

And because it does both, it does the thing neither half can alone:

🧠 Cap‑aware deferral — a prompt scheduled for 2am is never fired into a capped pane and lost. claudekeeper holds it until the cap resets, then submits it.

It's dependency‑free Python driven entirely through the tmux CLI, so it runs anywhere tmux does — Linux boxes, HPC login nodes, macOS.

🚀 Install

One‑liner (recommended):

curl -fsSL https://raw.githubusercontent.com/PursuitOfDataScience/claudekeeper/main/install.sh | sh

Drops claudekeeper in ~/.local/share/claudekeeper and a launcher at ~/.local/bin/claudekeeper. The only runtime requirements are python3 ≥ 3.8 and tmux — both already on almost any machine you'd run Claude Code on. No pip, no virtualenv, nothing to compile.

Or via a Python package manager:

uv tool install claudekeeper      # or:  pipx install claudekeeper
Why not npm i -g?

npm installs Node programs; claudekeeper is Python. The Python equivalent of npm's global one‑liner is uv tool install / pipx install above, or the curl | sh script (which needs nothing but python3). If ~/.local/bin isn't on your PATH, the installer tells you how to add it.

⚡ Quickstart

claudekeeper setup                              # 1. one-time: start the background daemon

# 2. Open Claude Code in a tmux session, type your prompt, DON'T hit enter — then:
claudekeeper schedule mysession 2am             #    claudekeeper presses Enter at 2am
claudekeeper schedule mysession "now + 30min" --prompt "run the full test suite"

# 3. (optional) auto-resume after the usage cap:
claudekeeper watch on

claudekeeper status                             # the daemon, your jobs, your sessions
claudekeeper logs -f                            # watch what it does, live

Run claudekeeper with no arguments any time for a refresher — it even lists the Claude sessions you have running right now.

🧭 The mental model (read this once)

claudekeeper has two moving parts:

  1. A background daemon (claudekeeper setup installs it). It's the thing that actually presses keys. Scheduled jobs only fire while the daemon is running — the one gotcha, and claudekeeper schedule warns you if it isn't.
  2. A job list + settings you manage from the CLI (schedule, ls, rm, watch on/off). The daemon reads these live.

You pre‑type your prompt into the Claude Code input box and leave it there; claudekeeper submits it for you (a single Enter) at the right moment. With --prompt "...", claudekeeper types the text for you instead.

📖 Commands

Command What it does
claudekeeper setup Install + start the daemon, then print personalized next steps
claudekeeper schedule <target> <time> [--prompt T] [--daily] [--force] Arm a keypress. <target> is a tmux session or session:win.pane.
claudekeeper ls List scheduled jobs (with ETA and any deferral)
claudekeeper rm <id|all> Cancel a job
claudekeeper watch on|off|status Toggle cap auto‑resume (off by default)
claudekeeper status Daemon state, jobs, detected Claude panes
claudekeeper logs [-f] [-n N] View / follow activity
claudekeeper service install|uninstall|start|stop|status Manage the daemon directly
claudekeeper daemon Run the loop in the foreground (what the service runs)
claudekeeper doctor Check python, tmux, service manager, paths

Time formats: 2am, 3pm, 9:30am, 14:30, 22:00, now + 5min, +10m, in 90s, noon, midnight, teatime.

🛡️ Safety

claudekeeper automates keystrokes into your terminals. It's built fail‑safe, but be aware:

  • Auto‑resume is opt‑in. watch is off until you run claudekeeper watch on. Out of the box claudekeeper only fires prompts you explicitly schedule.
  • A cap is only a cap if the pane shows a real reset time. Auto‑resume ignores API errors, scrollback, and mere chatter about limits — it acts only on a parseable "resets H:MM am/pm". Each cap is resumed once, and only re‑arms after the pane is seen working again, so it can never loop and drain your budget.
  • A blind Enter lands on whatever has focus. If a pane is sitting on a tool‑permission prompt whose default is destructive, an Enter would accept it. Schedule against panes you've left at the prompt with your text staged.
  • It's node‑local. The daemon watches the tmux server on the machine it runs on; run it on the same host as your sessions.

⚙️ Configuration

Settings live in ~/.local/state/claudekeeper/config.json (override the dir with CLAUDEKEEPER_HOME). Toggle the common one with claudekeeper watch on/off; edit the file for the rest (msg, poll, buffer, stagger, match_command, only, exclude, …). The daemon re‑reads it every loop, so changes take effect without a restart, and out‑of‑range or wrong‑type values are clamped to safe defaults rather than crashing the daemon. Set CLAUDEKEEPER_TMUX to point at a specific tmux binary.

Keep CLAUDEKEEPER_HOME on a local filesystem. claudekeeper serializes its state with flock, which is only reliable on local disks — on some network filesystems (NFS) cross‑host locking is a no‑op. claudekeeper is node‑local anyway.

🔬 How it works

A single loop, every poll seconds:

  1. list tmux panes whose command is claude, capture each one's text;
  2. if watch is on, detect real caps and schedule a one‑time resume at reset + buffer (staggered across sessions);
  3. fire any due scheduled jobs — deferring any whose target pane is currently capped.

Scheduled jobs are persisted before the keypress (at‑most‑once — a crash never double‑fires a prompt into Claude) and are never lost to a momentary tmux/session outage. Handled caps persist across restarts, so a restart never re‑fires an already‑handled cap. Only one daemon runs per CLAUDEKEEPER_HOME (single‑instance lock).

🧪 Development

git clone https://github.com/PursuitOfDataScience/claudekeeper && cd claudekeeper
PYTHONPATH=src python3 -m claudekeeper doctor
for f in tests/test_*.py; do PYTHONPATH=src python3 "$f"; done   # unit tests (no deps)

⚖️ Disclaimer

claudekeeper is an independent, community‑built tool. It is not affiliated with, endorsed by, or sponsored by Anthropic. "Claude" and "Claude Code" are trademarks of Anthropic, PBC — used here only to describe what the tool works with. claudekeeper just automates the tmux CLI around Claude Code sessions you run yourself.

📄 License

MIT © 2026 PursuitOfDataScience

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

claudekeeper-0.1.1.tar.gz (120.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claudekeeper-0.1.1-py3-none-any.whl (27.0 kB view details)

Uploaded Python 3

File details

Details for the file claudekeeper-0.1.1.tar.gz.

File metadata

  • Download URL: claudekeeper-0.1.1.tar.gz
  • Upload date:
  • Size: 120.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for claudekeeper-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e1a2f018ea5510260bca7ae5062f2f7e4424dab6d6c6f43884003190bfc0cec7
MD5 6ea294fe862e136ade3dae2a85a6cf20
BLAKE2b-256 bf251462618c5c6feb34cb3779778e27d1c16fedaa0b08a9d9767cf3be48aea1

See more details on using hashes here.

Provenance

The following attestation bundles were made for claudekeeper-0.1.1.tar.gz:

Publisher: publish.yml on PursuitOfDataScience/claudekeeper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file claudekeeper-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: claudekeeper-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 27.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for claudekeeper-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3ab27acd804def113f5f07aa3da37063fd76c0dd44b2bfae1c66cffc2f13f0a8
MD5 8e33149d111d389fb52c322eda39066e
BLAKE2b-256 77d257b95e9a2c35c9c1d36ff13c74e11801b174a6cb2e52fe2c52c8d2cb828d

See more details on using hashes here.

Provenance

The following attestation bundles were made for claudekeeper-0.1.1-py3-none-any.whl:

Publisher: publish.yml on PursuitOfDataScience/claudekeeper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page