Automated monitoring and restart system for Claude Code usage limits
Features • Installation • Quick Start • Documentation • Contributing
ClaudeCodeLooper automatically detects Claude Code's 5-hour usage limits, manages the cooldown period, and restarts your session seamlessly. Work for extended periods without interruption or manual intervention.
Perfect for:
- Long coding sessions
- CI/CD pipelines
- Automated workflows
- Production environments
- 🔍 Automatic Detection: Real-time monitoring of Claude Code output for usage limit patterns
- ⏰ Precise Timing: Accurate 5-hour countdown tracking with automatic restart
- 🔄 Background Operation: Daemon mode for uninterrupted workflow
- 💬 Claude Code Integration: Convenient slash commands (
/cl:on,/cl:off,/cl:status,/cl:logs) - 🛡️ Resilient: Graceful shutdown and state persistence across system restarts
- 📊 Comprehensive Logging: Structured JSON logging for complete event tracking
- 🔒 Secure: Shell injection prevention, path traversal protection, input sanitization
- Python: 3.9 or higher
- OS: Windows, macOS, Linux (WSL supported)
- Claude Code: Must be installed and accessible
# Install / upgrade to the latest release
pip install --upgrade claude-code-looper
# Verify installation
claude-looper --version# Install from the tip of main
pip install --upgrade git+https://github.com/LEE-Kyungjae/ClaudeCodeLooper.git# Clone repository
git clone https://github.com/LEE-Kyungjae/ClaudeCodeLooper.git
cd ClaudeCodeLooper
# Run installer (macOS/Linux)
./install.sh
# Run installer (Windows)
install.bat# Clone repository
git clone https://github.com/LEE-Kyungjae/ClaudeCodeLooper.git
cd ClaudeCodeLooper
# Install in development mode
pip install -e ".[dev]"
# Or standard installation
pip install -e .# Start monitoring (daemon mode)
claude-looper start --claude-cmd "claude" --work-dir "$PWD" --daemon
# Check status
claude-looper status
# View logs
claude-looper logs --tail 50
# Stop monitoring
claude-looper stop --allIf you're using Claude Code, it's even simpler:
/cl:on # Start monitoring
/cl:status # Check status
/cl:logs # View logs
/cl:off # Stop monitoring
💡 Tip: Slash commands automatically format output with emoji indicators for better readability!
# Start work in the morning
/cl:on
# [Work normally throughout the day]
# [System automatically detects when 5-hour limit is reached]
# [System waits for 5-hour cooldown period]
# [Claude Code automatically restarts]
# Finish work in the evening
/cl:off# Use in automated workflow
claude-looper start \
--claude-cmd "claude --no-interactive" \
--work-dir "/path/to/project" \
--daemon
# Run pipeline tasks
# ...
# Clean up after completion
claude-looper stop --all# Monitor Project A
cd /path/to/project-a
claude-looper start --claude-cmd "claude" --daemon
# Monitor Project B
cd /path/to/project-b
claude-looper start --claude-cmd "claude" --daemon
# Check all session statuses
claude-looper status --verbose- Default Config:
config/default.json - User Config:
.claude-restart-config.json(create in project root)
Create .claude-restart-config.json to customize settings:
{
"detection": {
"patterns": [
"usage limit exceeded",
"wait (\\d+) hours?"
],
"confidence_threshold": 0.7
},
"timing": {
"wait_hours": 5,
"check_interval_seconds": 60
},
"restart": {
"max_retries": 3,
"retry_delay_seconds": 10
},
"logging": {
"level": "INFO",
"file": "logs/claude-restart-monitor.log"
}
}claude-looper start [OPTIONS]
Options:
--claude-cmd TEXT Claude Code command to run [default: claude]
--work-dir TEXT Working directory [default: current directory]
--daemon Run in background daemon mode
--config TEXT Path to config file
--session-id TEXT Session ID (optional; auto-generated)Examples:
# Start with defaults
claude-looper start
# Run as a daemon
claude-looper start --daemon
# Start with a custom config
claude-looper start --config /path/to/config.json --daemonclaude-looper stop [OPTIONS]
Options:
--session-id TEXT Stop a specific session
--all Stop all sessions
--force Force shutdownExamples:
# Gracefully stop every session
claude-looper stop --all
# Stop a particular session
claude-looper stop --session-id sess_abc123
# Force termination
claude-looper stop --all --forceclaude-looper status [OPTIONS]
Options:
--verbose Show detailed information
--format [text|json] Output format
--session-id TEXT Status of a specific sessionExamples:
# Basic status
claude-looper status
# Detailed output
claude-looper status --verbose
# JSON output
claude-looper status --format jsonclaude-looper logs [OPTIONS]
Options:
--tail INTEGER Show the last N lines [default: 50]
--follow Stream logs in real time
--filter TEXT Filter logs (detection, error, warning)
--session-id TEXT Logs for a specific sessionExamples:
# Last 50 lines
claude-looper logs
# Last 100 lines
claude-looper logs --tail 100
# Live stream
claude-looper logs --follow
# Only errors
claude-looper logs --filter error
# Detection events only
claude-looper logs --filter detectionclaude-looper config [OPTIONS]
Options:
--show Display the current configuration
--set KEY VALUE Change a configuration value
--reset Reset to defaultsExamples:
# View configuration
claude-looper config --show
# Change wait time
claude-looper config --set timing.wait_hours 6
# Reset to defaults
claude-looper config --resetclaude-looper queue [COMMAND]
Commands:
add <text> Add a task that runs after the next restart
list Show queued tasks in execution order
remove <nums...> Remove tasks by their list numbers
clear Clear the queue (use --confirm to skip prompt)
templates List predefined templates and guidelinesExamples:
# Check available templates
claude-looper queue templates
# Add a task with template + extra checklist + follow-up command
claude-looper queue add \
--template backend_feature \
--guideline "DB 마이그레이션 영향 검토" \
--post "pytest tests/api" \
"에러 로깅 개선"
# Inspect the queue
claude-looper queue list
# Remove tasks 1 and 3
claude-looper queue remove 1 3# 1. Inspect logs
claude-looper logs --filter error
# 2. Check permissions
ls -la logs/
# 3. Confirm Python version
python --version # Requires 3.9+
# 4. Reinstall dependencies
pip install -r requirements.txt --force-reinstall# 1. Check detection patterns
claude-looper logs --filter detection
# 2. Verify configuration
claude-looper config --show
# 3. Inspect detailed status
claude-looper status --verbose# 1. Confirm Claude Code is installed
which claude
# 2. Check PATH
echo $PATH
# 3. Use an absolute path
claude-looper start --claude-cmd "/full/path/to/claude"# Clean up the log file
rm logs/claude-restart-monitor.log
# Or reduce the log level
claude-looper config --set logging.level WARNING# Clone repository
git clone https://github.com/LEE-Kyungjae/ClaudeCodeLooper.git
cd ClaudeCodeLooper
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Lint and type-check
black src/ tests/
flake8 src/ tests/
mypy src/ClaudeCodeLooper/
├── src/
│ ├── cli/ # CLI interface
│ │ ├── main.py
│ │ └── commands/ # Command implementations
│ ├── models/ # Data models (Pydantic)
│ ├── services/ # Core services
│ │ ├── process_monitor.py # Process monitoring orchestrator
│ │ ├── process_launcher.py # Process launch management
│ │ ├── output_capture.py # Output capture
│ │ ├── health_checker.py # Health monitoring
│ │ ├── pattern_detector.py # Pattern detection
│ │ └── restart_controller.py # Restart control
│ ├── utils/ # Utilities
│ │ └── logging.py # Structured logging
│ └── exceptions.py # Exception hierarchy
├── tests/
│ ├── contract/ # Contract tests
│ ├── integration/ # Integration tests
│ └── unit/ # Unit tests
├── config/
│ └── default.json # Default configuration
├── .claude/
│ └── commands/ # Claude Code slash commands
└── docs/ # Additional documentation
# tests/unit/services/test_example.py
import pytest
from src.services.process_monitor import ProcessMonitor
def test_monitor_initialization():
monitor = ProcessMonitor(config)
assert monitor is not None
@pytest.mark.asyncio
async def test_async_operation():
# Async test example
pass- Create a branch:
git checkout -b feature/your-feature - Write tests: Start with TDD when possible
- Implement: Make the tests pass
- Run quality checks: Execute
black,flake8, andmypy - Commit: Use clear, descriptive messages
- Open a Pull Request: Target the main branch
MIT License - free to use, modify, and distribute.
Bug reports, feature suggestions, and pull requests are always welcome!
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- Issues: GitHub Issues
- Documentation: Wiki
- Email: ze2@kakao.com
We built this project to make working with Claude Code easier. Feedback and contributions are appreciated!
We follow a trunk + development workflow:
main— production-ready code. Release tags (vX.Y.Z) are created from here and published to PyPI automatically.develop— integration branch. All new work is merged here via pull requests before being promoted tomain.- Feature branches — created from
developfor new work:feature/<topic>. - Hotfix branches — created from
mainfor urgent fixes:hotfix/<issue>and merged back into bothmainanddevelop.
- Create a feature branch from
develop(feature/<name>). - Ensure linting and tests succeed (
pip install -e ".[dev]"thenpytest). - Open a PR into
develop, describe the change, and request review. - Once approved and merged into
develop, maintainers promote changes tomainduring release cycles.
- Update the version in
pyproject.tomland commit ondevelop. - Merge
develop->mainvia PR. - Tag
mainwithvX.Y.Zand push; GitHub Actions builds and publishes to PyPI automatically.
Contributions, bug reports, and feature ideas are welcome! Please open an issue or submit a pull request following the guidelines above.
Made with ❤️ for Claude Code users