
Ralph Wiggum plugin implementation that works after the CVE-2025-54795 security patch
A working implementation of the Ralph Wiggum autonomous loop technique for Claude Code.
The official ralph-wiggum plugin in Anthropic's plugin marketplace is currently broken due to a security update in Claude Code v1.0.20 (August 2025).
The security patch (CVE-2025-54795) correctly blocks $() command substitution and multi-line bash commands to prevent command injection attacks. However, the official plugin's command file contains multi-line bash that triggers this protection:
Error: Bash command permission check failed for pattern "...":
Command contains newlines that could separate multiple commands
Multiple issues have been filed:
As of January 3, 2026, these remain unfixed.
This is a clean reimplementation that works with current Claude Code security restrictions.
Key architectural difference: The official plugin tries to execute bash directly from the command file. This plugin instead instructs Claude to create the state file using its Write tool, keeping the command file pure markdown with no bash execution. The stop hook runs as a separate shell script outside the permission system.
claude --plugin-dir /path/to/ralph
# Create marketplace
mkdir -p ~/claude-plugins/.claude-plugin
echo '{"name": "local", "owner": {"name": "You"}}' > ~/claude-plugins/.claude-plugin/marketplace.json
# Move plugin into marketplace
mv /path/to/ralph ~/claude-plugins/
# In Claude Code:
/plugin marketplace add ~/claude-plugins
/plugin install ralph@local
/ralph:ralph-loop "Your task" --max-iterations 30 --completion-promise "DONE"
| Argument | Description | Default |
|---|---|---|
| prompt | The task to complete | (required) |
| --max-iterations N | Safety limit | 30 |
| --completion-promise TEXT | Completion signal | TASK_COMPLETE |
/ralph:ralph-loop "Build a REST API with tests" --completion-promise "API_COMPLETE"
/ralph:ralph-loop "Follow the instructions in CLAUDE.md" --max-iterations 50 --completion-promise "BENCHMARK_COMPLETE"
/ralph:cancel-ralph
.claude/ralph-loop.local.md with task and config<promise>COMPLETION_PROMISE</promise>{"decision": "block", "reason": "..."}, Claude continuesjq (for JSON parsing in stop hook)MIT