chore: add loop state migration from .claude/ to .agent/loop-state/#67
chore: add loop state migration from .claude/ to .agent/loop-state/#67marcusquinn merged 1 commit intomainfrom
Conversation
Handles the breaking change from v2.51.0 where loop state directory moved. The migration: - Scans ~/Git/ for repositories with .claude/ loop state - Moves ralph-loop.local.md, loop-state.json, receipts/, etc. - Updates .gitignore if needed - Removes empty .claude/ directories - Non-destructive: preserves other files in .claude/
|
Warning Rate limit exceeded@marcusquinn has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 19 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a breaking change introduced in v2.51.0 by providing an automated migration path for user loop state directories. It ensures that legacy loop state files are correctly moved from the old Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Mon Jan 12 17:10:52 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
🤖 Augment PR SummarySummary: Adds an automated migration step in Changes:
🤖 Was this summary useful? React with 👍 or 👎 |
|
|
||
| # Migrate loop state from .claude/ to .agent/loop-state/ in user projects | ||
| # This handles the breaking change from v2.51.0 where loop state directory moved | ||
| # The migration is non-destructive: moves files, doesn't delete originals until confirmed |
There was a problem hiding this comment.
This comment says the migration "doesn't delete originals until confirmed", but the implementation uses mv and no confirmation, so the originals are removed immediately. Consider aligning the comment with the actual behavior so users don’t assume a reversible/verified migration.
🤖 Was this useful? React with 👍 or 👎
|
|
||
| # Check for loop state files in old location | ||
| local has_loop_state=false | ||
| if [[ -f "$old_state_dir/ralph-loop.local.md" ]] || \ |
| # Move loop-related files | ||
| for file in ralph-loop.local.md loop-state.json re-anchor.md guardrails.md; do | ||
| if [[ -f "$old_state_dir/$file" ]]; then | ||
| mv "$old_state_dir/$file" "$new_state_dir/" |
There was a problem hiding this comment.
These mv operations can overwrite existing files in $new_state_dir if users already have new-format state (or rerun migration), which risks losing the newer state. Also, if $new_state_dir/receipts already exists, mv can result in a nested receipts/receipts directory.
🤖 Was this useful? React with 👍 or 👎
There was a problem hiding this comment.
Code Review
This pull request introduces a migration script to move loop state files from the legacy .claude/ directory to the new .agent/loop-state/ location. The implementation is well-structured, but I've identified a significant correctness issue where the script fails to detect all files intended for migration, potentially leaving some repositories in an inconsistent state. Additionally, there's an opportunity to improve the robustness of a directory check. My review includes specific code suggestions to address these points.
| local has_loop_state=false | ||
| if [[ -f "$old_state_dir/ralph-loop.local.md" ]] || \ | ||
| [[ -f "$old_state_dir/loop-state.json" ]] || \ | ||
| [[ -d "$old_state_dir/receipts" ]]; then | ||
| has_loop_state=true | ||
| fi | ||
|
|
||
| [[ "$has_loop_state" != "true" ]] && continue |
There was a problem hiding this comment.
The check for legacy loop state files is incomplete. It's missing re-anchor.md and guardrails.md, which are moved later in the script (line 248). This means if a .claude directory only contains one of these files, the migration for that repository will be skipped. This is a correctness issue.
Additionally, the logic using a has_loop_state flag is verbose and can be simplified into a more direct check. The suggested change below fixes the bug and improves readability by combining the check and the conditional continuation.
| local has_loop_state=false | |
| if [[ -f "$old_state_dir/ralph-loop.local.md" ]] || \ | |
| [[ -f "$old_state_dir/loop-state.json" ]] || \ | |
| [[ -d "$old_state_dir/receipts" ]]; then | |
| has_loop_state=true | |
| fi | |
| [[ "$has_loop_state" != "true" ]] && continue | |
| if ! [[ -f "$old_state_dir/ralph-loop.local.md" || \ | |
| -f "$old_state_dir/loop-state.json" || \ | |
| -d "$old_state_dir/receipts" || \ | |
| -f "$old_state_dir/re-anchor.md" || \ | |
| -f "$old_state_dir/guardrails.md" ]]; then | |
| continue | |
| fi | |
| remaining=$(find "$old_state_dir" -mindepth 1 -maxdepth 1 2>/dev/null | wc -l | tr -d ' ') | ||
|
|
||
| if [[ "$remaining" -eq 0 ]]; then | ||
| rmdir "$old_state_dir" 2>/dev/null && print_info " Removed empty .claude/" | ||
| else | ||
| print_warning " .claude/ has other files, not removing" | ||
| fi |
There was a problem hiding this comment.
The use of find ... | wc -l to check if a directory is empty is not fully robust, as it can miscount if filenames contain newline characters. A more standard and safer approach is to check if the output of ls -A is empty. This avoids parsing find's output and is a common idiom for this purpose.
| remaining=$(find "$old_state_dir" -mindepth 1 -maxdepth 1 2>/dev/null | wc -l | tr -d ' ') | |
| if [[ "$remaining" -eq 0 ]]; then | |
| rmdir "$old_state_dir" 2>/dev/null && print_info " Removed empty .claude/" | |
| else | |
| print_warning " .claude/ has other files, not removing" | |
| fi | |
| remaining=$(ls -A -- "$old_state_dir" 2>/dev/null) | |
| if [[ -z "$remaining" ]]; then | |
| rmdir "$old_state_dir" 2>/dev/null && print_info " Removed empty .claude/" | |
| else | |
| print_warning " .claude/ has other files, not removing" | |
| fi |



Summary
Handles the breaking change from v2.51.0 where loop state directory moved from
.claude/to.agent/loop-state/.What This Does
When users run
setup.sh, it now:~/Git/for repositories with.claude/loop state files.agent/loop-state/:ralph-loop.local.mdloop-state.jsonre-anchor.mdguardrails.mdreceipts/directory.gitignoreif needed.claude/directories.claude/(non-destructive)Why This Is Needed
PR #65 moved loop state from
.claude/to.agent/loop-state/with backward compatibility in the scripts (they check both locations). However, without migration:.claude/directories would accumulate cruftTesting
.claude/directory