74 tests pass, 0 typecheck errors, 0 lint errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Overnight Claude Automation
Run Claude Code autonomously while you're away. Combines sleep prevention, task-based execution, the Ralph Wiggum Technique (Stop hook blocks until plan is complete), and security hooks that restrict AI to project files and block destructive commands.
Prerequisites
- Claude Code CLI (claude.ai/code) — installed at
~/.local/bin/claudeor in PATH - Hooks — user-level hooks in
~/.claude/(sleep, Ralph Wiggum) - jq — for security hook scripts (
brew install jq)
Flow
Pre-run (before 5–6pm)
-
Commit and push — Snap current work and back up to remote.
-
Run prepare script — Creates date-stamped branch and verifies clean state:
./loop/prepare.sh -
Edit plan — Update
loop/plan.mdwith evening scope and tasks (see template below). -
Commit plan — Version the plan so you can revert if needed:
git add loop/plan.md && git commit -m "chore: overnight plan $(date +%Y-%m-%d)" -
Push (optional but recommended):
git push -u origin overnight/YYYY-MM-DD
Overnight
tmux new -s overnight
caffeinate -i ./loop/loop.sh
# Detach: Ctrl+B, then D
Post-run (next morning)
git statusandgit diffto review changes.- Run
pnpm test && pnpm lint && pnpm typecheck. - Merge branch or revert if needed.
Quick Start
-
Edit your plan — Add tasks to
loop/plan.mdusing the evening run format:# Evening Run — YYYY-MM-DD ## Scope Add tests to chat components. ## Tasks - [ ] Add unit tests for useAI composable - [ ] Fix linter errors in packages/app -
Run overnight — From project root:
caffeinate -i ./loop/loop.sh
How It Works
| Component | Purpose |
|---|---|
| UserPromptSubmit hook | Starts caffeinate to prevent Mac sleep when you submit a prompt |
| Stop hook | Checks plan.md for unchecked tasks; blocks Claude from stopping until all are done (Ralph Wiggum) |
| SessionEnd hook | Kills caffeinate so Mac can sleep again |
| PreToolUse (Bash) | Blocks dangerous commands (rm -rf, git reset --hard, etc.) |
| PreToolUse (Edit|Write) | Blocks edits outside project and to protected paths |
| loop.sh | Runs Claude with --dangerously-skip-permissions and feeds the prompt from loop/prompt.md |
Security Model
Project-scoped hooks in .claude/hooks/ restrict the AI during overnight runs:
Bash guard (block-risky-bash.sh)
Blocks: rm -rf, git reset --hard, git push --force, git clean -fd, chmod -R 777, fork bombs, block device overwrites, mkfs, and path traversal with destructive commands.
File edit guard (protect-files.sh)
Blocks Edit/Write when:
- Path is outside project directory
- Path contains
.git/ - Path is
.env,.env.local,.env.*.local - Path is
package-lock.jsonorpnpm-lock.yaml - Path contains
node_modules/
Read, Glob, and Grep remain unrestricted.
Environment Variables
| Variable | Default | Description |
|---|---|---|
CLAUDE_AUTONOMOUS |
1 |
Set to 1 to enable Ralph Wiggum (Stop hook checks plan). 0 disables. |
CLAUDE_PLAN_FILE |
plan.md |
Plan file path (relative to project). |
ITERATION_COUNT |
1 |
Number of loop iterations (use >1 for multi-run without Ralph Wiggum). |
ITERATION_DELAY |
600 |
Seconds between iterations when ITERATION_COUNT > 1. |
PROMPT_FILE |
loop/prompt.md |
Prompt content for Claude. |
LOG_FILE |
loop/loop.log |
Log output (gitignored). |
RATE_LIMIT_WAIT |
3600 |
Seconds to wait when rate limited (default 1 hour). |
MAX_RATE_LIMIT_RETRIES |
5 |
Max rate limit retries before scheduling launchd job. |
Rate Limit Handling
The loop script automatically detects rate limits (429, quota exceeded, etc.) and handles them:
- Inline retry — On first rate limit hit, sleeps for
RATE_LIMIT_WAITseconds (default 1 hour) and retries. - Escalating retries — Retries up to
MAX_RATE_LIMIT_RETRIEStimes with the same wait. - launchd fallback — After max retries, creates a self-cleaning launchd plist at
~/Library/LaunchAgents/com.aiui.overnight-retry.plistthat restarts the loop at the estimated reset time. The plist auto-removes after running.
This means you can walk away knowing the automation will survive rate limits overnight.
Scheduling (Optional)
Install claude-code-schedule for time-based runs:
cargo install claude-code-schedule
ccschedule --time 05:30 --message "Review plan.md and complete next task"
continuous-claude (Optional)
For full PR-based workflow (branches, PRs, CI):
# Install from https://github.com/AnandChowdhary/continuous-claude
continuous-claude -p "Work through loop/plan.md" -m 10 --max-duration 8h
Remote Monitoring
- Tmux + SSH: Attach from another machine:
ssh host 'tmux attach -t overnight' - Tailscale: Use Tailscale for easy remote SSH when away from home network
- Log tail:
tail -f loop/loop.logto watch progress
Safety
- Start small — Test with 1–2 tasks before overnight runs
- prepare.sh — Run before starting; fails if working tree is dirty or branch exists
- Git — Loop does not auto-commit; you review and merge in the morning
--dangerously-skip-permissions— Security hooks still run and block dangerous actions- Project-scoped hooks — Only apply when Claude runs in AIUI; other projects unaffected