chore(.gitignore): add loop log file to ignore list
This commit is contained in:
+138
@@ -0,0 +1,138 @@
|
||||
# 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](https://claude.ai/code)) — installed at `~/.local/bin/claude` or 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)
|
||||
|
||||
1. **Commit and push** — Snap current work and back up to remote.
|
||||
2. **Run prepare script** — Creates date-stamped branch and verifies clean state:
|
||||
|
||||
```bash
|
||||
./loop/prepare.sh
|
||||
```
|
||||
|
||||
3. **Edit plan** — Update `loop/plan.md` with evening scope and tasks (see template below).
|
||||
4. **Commit plan** — Version the plan so you can revert if needed:
|
||||
|
||||
```bash
|
||||
git add loop/plan.md && git commit -m "chore: overnight plan $(date +%Y-%m-%d)"
|
||||
```
|
||||
|
||||
5. **Push** (optional but recommended): `git push -u origin overnight/YYYY-MM-DD`
|
||||
|
||||
### Overnight
|
||||
|
||||
```bash
|
||||
tmux new -s overnight
|
||||
caffeinate -i ./loop/loop.sh
|
||||
# Detach: Ctrl+B, then D
|
||||
```
|
||||
|
||||
### Post-run (next morning)
|
||||
|
||||
1. `git status` and `git diff` to review changes.
|
||||
2. Run `pnpm test && pnpm lint && pnpm typecheck`.
|
||||
3. Merge branch or revert if needed.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Edit your plan** — Add tasks to `loop/plan.md` using the evening run format:
|
||||
|
||||
```markdown
|
||||
# Evening Run — YYYY-MM-DD
|
||||
|
||||
## Scope
|
||||
Add tests to chat components.
|
||||
|
||||
## Tasks
|
||||
- [ ] Add unit tests for useAI composable
|
||||
- [ ] Fix linter errors in packages/app
|
||||
```
|
||||
|
||||
2. **Run overnight** — From project root:
|
||||
|
||||
```bash
|
||||
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.json`** or **`pnpm-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). |
|
||||
|
||||
## Scheduling (Optional)
|
||||
|
||||
Install [claude-code-schedule](https://github.com/macalinao/claude-code-schedule) for time-based runs:
|
||||
|
||||
```bash
|
||||
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):
|
||||
|
||||
```bash
|
||||
# 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.log` to 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
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env sh
|
||||
# Headless loop script for overnight Claude Code automation.
|
||||
# Set CLAUDE_AUTONOMOUS=1 for Ralph Wiggum (Stop hook blocks until plan is complete).
|
||||
set -eu
|
||||
|
||||
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(cd "$(dirname "$0")/.." && pwd)}"
|
||||
PROMPT_FILE="${PROMPT_FILE:-$PROJECT_DIR/loop/prompt.md}"
|
||||
LOG_FILE="${LOG_FILE:-$PROJECT_DIR/loop/loop.log}"
|
||||
ITERATION_COUNT="${ITERATION_COUNT:-1}"
|
||||
ITERATION_DELAY="${ITERATION_DELAY:-600}"
|
||||
CLAUDE_BIN="${CLAUDE_BIN:-claude}"
|
||||
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
echo "=== Overnight loop started $(date '+%Y-%m-%dT%H:%M:%S' 2>/dev/null || date) ===" | tee -a "$LOG_FILE"
|
||||
echo " PROMPT_FILE=$PROMPT_FILE" | tee -a "$LOG_FILE"
|
||||
echo " CLAUDE_AUTONOMOUS=${CLAUDE_AUTONOMOUS:-0}" | tee -a "$LOG_FILE"
|
||||
echo " ITERATION_COUNT=$ITERATION_COUNT" | tee -a "$LOG_FILE"
|
||||
echo "" | tee -a "$LOG_FILE"
|
||||
|
||||
i=1
|
||||
while [ "$i" -le "$ITERATION_COUNT" ]; do
|
||||
echo "--- Iteration $i/$ITERATION_COUNT @ $(date '+%Y-%m-%dT%H:%M:%S' 2>/dev/null || date) ---" | tee -a "$LOG_FILE"
|
||||
export CLAUDE_PROJECT_DIR="$PROJECT_DIR"
|
||||
export CLAUDE_AUTONOMOUS="${CLAUDE_AUTONOMOUS:-1}"
|
||||
|
||||
# Run Claude with autonomous permissions; prompt from file
|
||||
if [ -f "$PROMPT_FILE" ]; then
|
||||
"$CLAUDE_BIN" -p --dangerously-skip-permissions --output-format=stream-json \
|
||||
< "$PROMPT_FILE" 2>&1 | tee -a "$LOG_FILE" || true
|
||||
else
|
||||
echo "Error: $PROMPT_FILE not found" | tee -a "$LOG_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
i=$((i + 1))
|
||||
if [ "$i" -le "$ITERATION_COUNT" ] && [ "$ITERATION_DELAY" -gt 0 ]; then
|
||||
echo "Waiting ${ITERATION_DELAY}s before next iteration..." | tee -a "$LOG_FILE"
|
||||
sleep "$ITERATION_DELAY"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "=== Loop complete $(date '+%Y-%m-%dT%H:%M:%S' 2>/dev/null || date) ===" | tee -a "$LOG_FILE"
|
||||
@@ -0,0 +1,38 @@
|
||||
# Evening Run — YYYY-MM-DD
|
||||
|
||||
> **Format**: Use `- [ ]` for incomplete, `- [x]` for complete. Enable autonomous mode with `CLAUDE_AUTONOMOUS=1` when running.
|
||||
|
||||
## Scope
|
||||
|
||||
Get the AIUI project to a green CI baseline: ESLint config, initial test coverage, and passing `pnpm test`, `pnpm lint`, `pnpm typecheck`. Work incrementally; complete as many tasks as possible.
|
||||
|
||||
## Pre-run checklist (you complete before 5–6pm)
|
||||
|
||||
- [ ] Committed all work; `git status` clean
|
||||
- [ ] Pushed to remote (or at least backed up)
|
||||
- [ ] Created branch for overnight: `git checkout -b overnight/YYYY-MM-DD`
|
||||
|
||||
## Instructions for Claude
|
||||
|
||||
Work through the checklist below. Complete one item per iteration, then update this file to mark it done. The Stop hook will keep you running until all tasks are checked. If a task is blocked or you hit a natural stopping point, add context to the Notes section and continue with the next task.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Add `eslint.config.js` (flat config) to `packages/app` for ESLint 10 — extend recommended Vue/TypeScript rules
|
||||
- [ ] Add `eslint.config.js` (flat config) to `packages/core` — same pattern as app
|
||||
- [ ] Add a minimal smoke test in `packages/core` (e.g. `src/index.test.ts`) so `pnpm test` no longer fails with "No test files found"
|
||||
- [ ] Add unit tests for `useTheme` composable in `packages/app` — test theme detection and toggle behavior
|
||||
- [ ] Run `pnpm lint` and fix any reported issues (or document known unfixable ones in Notes)
|
||||
- [ ] Add unit tests for `useAI` or `contentFiltering` composable — at least one meaningful test
|
||||
- [ ] Verify `pnpm test`, `pnpm lint`, `pnpm typecheck` all pass; fix failures
|
||||
- [ ] Update this plan's Success criteria section — mark items that pass
|
||||
|
||||
## Success criteria
|
||||
|
||||
- [ ] pnpm test passes
|
||||
- [ ] pnpm lint passes
|
||||
- [ ] No new linter/type errors
|
||||
|
||||
## Notes
|
||||
|
||||
(Claude will add context here for the next iteration.)
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env sh
|
||||
# Pre-run script: verify repo state and create overnight branch.
|
||||
# Run before 5-6pm to ensure you can safely start the overnight loop.
|
||||
set -eu
|
||||
|
||||
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(cd "$(dirname "$0")/.." && pwd)}"
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
DATE=$(date '+%Y-%m-%d')
|
||||
BRANCH="overnight/${DATE}"
|
||||
|
||||
echo "=== Overnight pre-run check @ $(date '+%Y-%m-%dT%H:%M:%S') ==="
|
||||
|
||||
# 1. Check git status is clean
|
||||
if ! git diff --quiet || ! git diff --cached --quiet; then
|
||||
echo "Error: Working tree not clean. Commit or stash changes first." >&2
|
||||
echo " git status" >&2
|
||||
git status --short >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. Check we're not already on an overnight branch
|
||||
current=$(git branch --show-current 2>/dev/null || true)
|
||||
if [ -n "$current" ] && [ "$current" = "$BRANCH" ]; then
|
||||
echo "Already on $BRANCH. Ready to run." >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 3. Create date-stamped branch
|
||||
if git rev-parse --verify "$BRANCH" >/dev/null 2>&1; then
|
||||
echo "Branch $BRANCH already exists. Checkout or use a different date." >&2
|
||||
exit 1
|
||||
fi
|
||||
git checkout -b "$BRANCH"
|
||||
echo "Created branch $BRANCH"
|
||||
|
||||
# 4. Remind to push
|
||||
echo ""
|
||||
echo "Reminder: Push before starting overnight run: git push -u origin $BRANCH"
|
||||
echo "Then run: caffeinate -i ./loop/loop.sh"
|
||||
echo "=== Ready ==="
|
||||
@@ -0,0 +1 @@
|
||||
Read `loop/plan.md` and work on the next incomplete task. Update the plan to mark completed items with `- [x]`. Add any relevant context to the Notes section for the next iteration. Do not stop until all tasks in the plan are complete.
|
||||
Reference in New Issue
Block a user