Metadata-Version: 2.4
Name: claudekeeper
Version: 0.1.1
Summary: Cap-aware tmux scheduler & auto-resume for Claude Code — schedule prompts and keep sessions running through the 5-hour usage limit.
Project-URL: Homepage, https://github.com/PursuitOfDataScience/claudekeeper
Project-URL: Repository, https://github.com/PursuitOfDataScience/claudekeeper.git
Project-URL: Documentation, https://github.com/PursuitOfDataScience/claudekeeper#readme
Project-URL: Issues, https://github.com/PursuitOfDataScience/claudekeeper/issues
Author-email: Youzhi Yu <yuyouzhi666@icloud.com>
License-Expression: MIT
License-File: LICENSE
Keywords: anthropic,auto-resume,automation,claude,claude-code,cli,cron,daemon,developer-tools,productivity,rate-limit,scheduler,terminal,tmux,usage-limit
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: System :: Shells
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown

<div align="center">

# ⏻ claudekeeper

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

[![CI](https://github.com/PursuitOfDataScience/claudekeeper/actions/workflows/ci.yml/badge.svg)](https://github.com/PursuitOfDataScience/claudekeeper/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
![Python](https://img.shields.io/badge/python-3.8%2B-blue.svg)
![Platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS-lightgrey.svg)
![Dependencies](https://img.shields.io/badge/dependencies-none-brightgreen.svg)

<img src="docs/demo.gif" alt="claudekeeper demo" width="820">

</div>

---

`claudekeeper` is a tiny background daemon that watches your [Claude Code](https://claude.com/claude-code) sessions running in [tmux](https://github.com/tmux/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 <kbd>Enter</kbd> 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):**

```sh
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:**

```sh
uv tool install claudekeeper      # or:  pipx install claudekeeper
```

<details>
<summary><b>Why not <code>npm i -g</code>?</b></summary>

`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.
</details>

## ⚡ Quickstart

```sh
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 <kbd>Enter</kbd>) 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 <kbd>Enter</kbd> lands on whatever has focus.** If a pane is sitting on a tool‑permission prompt whose default is destructive, an <kbd>Enter</kbd> 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

```sh
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](LICENSE) © 2026 [PursuitOfDataScience](https://github.com/PursuitOfDataScience)
