Improve loop
Autonomous codebase improvement loop for Claude Code
npx -y skills add benmarte/autoimprove --skill improve-loopAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Autonomous improvement loop for any codebase. Uses git worktrees to run every experiment in isolation — the main branch is never touched until a winning change is explicitly merged. Reads .claude/autoimprove/config.md for the measurement suite, then iterates: create worktree → propose → implement in worktree → measure → merge if improved, delete if not → log → repeat.
SKILL.md
10.3 KB, as published. Nobody here has run it
AutoImprove Loop Skill
Every experiment runs in an isolated git worktree. The main codebase is never modified during experiments. Only winning changes get squash-merged back.
Main branch ──────────────────────────────────── (never touched mid-session)
│ │
experiment-001 experiment-002
(kept ✅ → merge) (discarded ❌ → deleted)
Pre-flight checks
Before the first iteration, print each check as you run it:
━━━ Pre-flight ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ Config found
✓ Git working tree clean
✓ Base commit: abc1234
✓ Worktree directory ready
✓ Baseline score: XX/100
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Check
.claude/autoimprove/config.mdexists. If not, stop: "Run /autoimprove:setup first." - Check git is available:
git status - Confirm main working tree is clean. If not, stop: "Please commit or stash changes before running autoimprove."
- Record the base commit:
git rev-parse HEAD— all experiments branch from here. - Run the worktree skill's setup step to create
.claude/autoimprove/worktrees/and update.gitignore. - Run the measure skill in the main directory to get the BASELINE score.
- Report: "Baseline: XX/100. All experiments will run in isolated worktrees. Main branch is safe."
Session Header
After pre-flight passes, write a session header to .claude/autoimprove/log.md:
## Session — [ISO 8601 timestamp]
**Planned:** N iterations
**Focus:** "focus string" (or "all improvement areas" if none)
**Baseline:** XX/100
**Base commit:** [full SHA]
**Status:** IN_PROGRESS (0/N completed)
If the log file doesn't exist, create it with the project header first:
# .claude/autoimprove/log.md
> Generated by [autoimprove](https://github.com/benmarte/autoimprove) — Claude Code Plugin
> Project: **[project name]** · Stack: [detected stack] · Started: [date]
---
Then append the session header.
Continue Mode
When invoked with continue-mode parameters (from the /autoimprove:continue command), the loop behavior changes:
start_iteration— Start numbering from this value instead of 1total_iterations— Use this as the display total (e.g., "Iteration 5/10")session_mode— Ifcontinue, skip creating a new session header; instead update the existing one:- Update
**Planned:**to the new total if it changed - Update
**Status:**toIN_PROGRESS
- Update
baseline_score— If provided, skip baseline measurement and use this valueexperiment_offset— Start experiment numbering from this value to avoid branch name collisions
In continue mode, the pre-flight still runs (clean tree, config check, worktree setup) but skips creating a new session header and optionally skips baseline measurement.
Progress Updates
CRITICAL: At the start of every step, you MUST output a visible progress line to the user. Do not silently run tools — always print status first. Use this format:
━━━ Iteration N/TOTAL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔬 STEP_NAME: brief description of what's happening
Example progress lines:
━━━ Iteration 1/5 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔬 PROPOSE: Targeting error handling in src/api/client.ts
🔬 SNAPSHOT: Measuring BEFORE score...
🔬 IMPLEMENT: Adding try/catch to unhandled async calls
🔬 MEASURE: Measuring AFTER score...
🔬 DECIDE: 85 → 89 (+4 pts) — KEPT ✅
🔬 LOG: Recorded to .claude/autoimprove/log.md
Never run more than one step without printing a progress line. The user must always know what iteration you're on and what phase you're in.
The Loop
Step 1 — CREATE WORKTREE
Use the worktree skill to create a new isolated branch and directory:
EXPERIMENT_ID=$(printf "%03d" $N)
git worktree add -b "autoimprove/experiment-$EXPERIMENT_ID" \
".claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID"
All work for this iteration happens inside .claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID/.
The main directory is not touched.
Step 2 — PROPOSE
If a FOCUS string was provided: Every iteration targets that specific focus. Break the focus into file-by-file or function-by-function sub-tasks and tackle one per iteration. Do not rotate to other areas — stay on the focus until all iterations are used or the focus is fully addressed.
If no FOCUS was provided: Choose one focused improvement from the Improvement Areas in .claude/autoimprove/config.md. Rotate areas — don't repeat an area that failed last time.
State the hypothesis explicitly:
"I will [specific change] in [file(s)] because I expect [metric] to improve by ~[X] points."
Step 3 — SNAPSHOT (BEFORE score)
Measure from inside the worktree directory (same commands, different cwd):
cd .claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID
# run measurement suite from .claude/autoimprove/config.md
Record as BEFORE.
Step 4 — IMPLEMENT
Make the change inside the worktree. The main directory is untouched. Commit the change to the experiment branch:
cd .claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID
git add -A
git commit -m "experiment($EXPERIMENT_ID): $HYPOTHESIS_ONE_LINE"
Step 5 — MEASURE (AFTER score)
Run the full measurement suite again from inside the worktree. Record as AFTER.
Step 6 — DECIDE
If AFTER > BEFORE — KEEP ✅
Squash-merge the experiment back to main:
cd [main project root]
git merge --squash "autoimprove/experiment-$EXPERIMENT_ID"
git commit -m "autoimprove($EXPERIMENT_ID): $HYPOTHESIS_ONE_LINE
Score: $BEFORE → $AFTER (+$DELTA pts)
Files changed: $FILES"
# Clean up
git worktree remove ".claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID"
git branch -D "autoimprove/experiment-$EXPERIMENT_ID"
If AFTER == BEFORE — KEEP ✅ only for clear readability wins, DISCARD otherwise
Same merge process as above if keeping, discard process if not.
If AFTER < BEFORE — DISCARD ❌
Main branch is already untouched. Just delete the worktree:
git worktree remove ".claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID" --force
git branch -D "autoimprove/experiment-$EXPERIMENT_ID"
No rollback needed — there was nothing to roll back.
Step 7 — LOG
Append to .claude/autoimprove/log.md in the main directory:
## Iteration N — [timestamp]
**Hypothesis:** [what you tried and why]
**Branch:** autoimprove/experiment-NNN
**Files changed:** [list]
**Before:** [X/100] — type: X, build: X, tests: X, lint: X
**After:** [X/100] — type: X, build: X, tests: X, lint: X
**Decision:** KEPT ✅ (merged to main) / DISCARDED ❌ (worktree deleted)
**Reason:** [one sentence]
Step 7b — UPDATE SESSION STATUS
After logging the iteration, update the session header's **Status:** line:
- Read
.claude/autoimprove/log.md - Find the last line matching
**Status:** IN_PROGRESS - Replace it with
**Status:** IN_PROGRESS (N/M completed)where N is the current iteration number and M is the total planned - Write the file back
If the status line cannot be found, append a warning to the log and continue — the iteration records are the source of truth.
Step 8 — REPEAT from Step 1
Session end — cleanup
After all iterations (or if the user stops early):
Update the session header status to completed:
- Read
.claude/autoimprove/log.md - Find the last
**Status:** IN_PROGRESSline - Replace with
**Status:** COMPLETED (N/N) - Write the file back
# Remove any remaining experiment worktrees
for wt in .claude/autoimprove/worktrees/experiment-*; do
git worktree remove "$wt" --force 2>/dev/null
done
git branch | grep "autoimprove/experiment" | xargs git branch -D 2>/dev/null
rm -rf .claude/autoimprove/worktrees
Print a final summary table:
━━━ Session Complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 Score: BASELINE → FINAL (+/- DELTA)
🔁 Iterations: N total — X kept ✅, Y discarded ❌
📝 Merged commits:
• abc1234 autoimprove(001): description
• def5678 autoimprove(003): description
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Universal Improvement Areas
Rotate through these (add language-specific ones from .claude/autoimprove/config.md):
- Type safety — fix type errors, replace
any/interface{}/untyped constructs - Error handling — unhandled promises, bare
catch {}, swallowed errors - Dead code — unused imports, variables, unreachable branches
- Code duplication — extract repeated logic (3+ occurrences) into shared utilities
- Naming & readability — cryptic names, functions over ~50 lines
- Performance — N+1 query patterns, missing memoization, unnecessary allocations
- Security — hardcoded secrets, missing input validation, unguarded auth routes
- Tests — add a test for the most critical untested function, fix flaky tests
Safety Rules
- Main branch is never modified until a winning experiment is explicitly squash-merged
- Never modify lock files, generated files, migrations,
.env— in any worktree - Never run deploy, publish, or push commands
- If the same area fails 3 iterations in a row, skip it and note in the log
- After 10 iterations, pause, clean up worktrees, and wait for human review
- On any unexpected error: run the worktree skill's cleanup step, then stop and report