Add missing repository components for complete supercharge.sh installation
Added all directories and files expected by supercharge.sh: - hooks/ (5 hook scripts for session management and AI consultation) - commands/ (3 custom slash commands: brainstorm, write-plan, execute-plan) - plugins/ (plugin references for glm-plan, rust-analyzer, marketplaces) - bin/ralphloop (Ralph Orchestrator wrapper for autonomous iteration) - scripts/sync-agents.sh (agent synchronization script) - templates/ (config templates: settings, hooks, config.json) This completes the repository structure so supercharge.sh can install all components without warnings. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
282
bin/ralphloop
Executable file
282
bin/ralphloop
Executable file
@@ -0,0 +1,282 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
RalphLoop - Ralph Orchestrator Wrapper for Claude Code
|
||||
|
||||
This wrapper integrates Ralph Orchestrator with Claude Code skills,
|
||||
providing autonomous "Tackle Until Solved" capabilities.
|
||||
|
||||
Environment Variables:
|
||||
RALPH_AGENT Agent to use (claude|gemini|kiro|q|auto)
|
||||
RALPH_MAX_ITERATIONS Maximum iterations (default: 100)
|
||||
RALPH_MAX_RUNTIME Maximum runtime in seconds (default: 14400)
|
||||
RALPH_VERBOSE Enable verbose output (default: false)
|
||||
|
||||
Usage:
|
||||
ralphloop "Design a microservices architecture"
|
||||
ralphloop --agent claude --max-iterations 50 "Implement auth"
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# Configuration
|
||||
DEFAULT_AGENT = os.getenv("RALPH_AGENT", "claude")
|
||||
DEFAULT_MAX_ITERATIONS = int(os.getenv("RALPH_MAX_ITERATIONS", 100))
|
||||
DEFAULT_MAX_RUNTIME = int(os.getenv("RALPH_MAX_RUNTIME", 14400))
|
||||
VERBOSE = os.getenv("RALPH_VERBOSE", "false").lower() == "true"
|
||||
|
||||
# Ralph directory
|
||||
RALPH_DIR = Path(".ralph")
|
||||
STATE_FILE = RALPH_DIR / "state.json"
|
||||
PROMPT_FILE = RALPH_DIR / "PROMPT.md"
|
||||
CONFIG_FILE = RALPH_DIR / "ralph.yml"
|
||||
ITERATIONS_DIR = RALPH_DIR / "iterations"
|
||||
|
||||
|
||||
def setup_ralph_directory():
|
||||
"""Create .ralph directory structure."""
|
||||
RALPH_DIR.mkdir(exist_ok=True)
|
||||
ITERATIONS_DIR.mkdir(exist_ok=True)
|
||||
|
||||
|
||||
def load_state():
|
||||
"""Load current Ralph state."""
|
||||
if STATE_FILE.exists():
|
||||
with open(STATE_FILE, "r") as f:
|
||||
return json.load(f)
|
||||
return {
|
||||
"iteration": 0,
|
||||
"status": "not_started",
|
||||
"started_at": None,
|
||||
"completed_at": None,
|
||||
"last_error": None
|
||||
}
|
||||
|
||||
|
||||
def save_state(state):
|
||||
"""Save Ralph state."""
|
||||
with open(STATE_FILE, "w") as f:
|
||||
json.dump(state, f, indent=2)
|
||||
|
||||
|
||||
def create_prompt(task, agent, max_iterations, max_runtime):
|
||||
"""Create PROMPT.md with task and success criteria."""
|
||||
prompt = f"""# RalphLoop Task
|
||||
|
||||
## Task
|
||||
{task}
|
||||
|
||||
## Success Criteria
|
||||
- Task fully analyzed and understood
|
||||
- All requirements addressed
|
||||
- Implementation/design complete
|
||||
- Quality standards met
|
||||
- No critical issues remaining
|
||||
|
||||
## Configuration
|
||||
- Agent: {agent}
|
||||
- Max Iterations: {max_iterations}
|
||||
- Max Runtime: {max_runtime} seconds ({timedelta(seconds=max_runtime)})
|
||||
- Started: {datetime.now().isoformat()}
|
||||
|
||||
## Instructions
|
||||
Run autonomous iterations until all success criteria are met.
|
||||
Update state.json after each iteration.
|
||||
Save final result to iterations/final.md when complete.
|
||||
"""
|
||||
with open(PROMPT_FILE, "w") as f:
|
||||
f.write(prompt)
|
||||
|
||||
|
||||
def create_config(agent, max_iterations, max_runtime):
|
||||
"""Create ralph.yml configuration."""
|
||||
config = f"""# RalphLoop Configuration
|
||||
agent: {agent}
|
||||
max_iterations: {max_iterations}
|
||||
max_runtime: {max_runtime}
|
||||
verbose: {VERBOSE}
|
||||
|
||||
# Output
|
||||
iterations_dir: iterations
|
||||
state_file: state.json
|
||||
final_output: iterations/final.md
|
||||
|
||||
# Claude Code Integration
|
||||
skill_path: ~/.claude/skills/ralph
|
||||
brainstorming_skill: ~/.claude/skills/brainstorming
|
||||
"""
|
||||
with open(CONFIG_FILE, "w") as f:
|
||||
f.write(config)
|
||||
|
||||
|
||||
def run_ralph_iteration(task, iteration, agent):
|
||||
"""Run a single Ralph iteration."""
|
||||
iteration_file = ITERATIONS_DIR / f"{iteration:03d}.md"
|
||||
|
||||
# Check if ralph-orchestrator is installed
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["ralph", "--agent", agent, "--prompt", task],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300
|
||||
)
|
||||
|
||||
output = result.stdout or result.stderr
|
||||
|
||||
with open(iteration_file, "w") as f:
|
||||
f.write(f"""# Iteration {iteration}
|
||||
|
||||
## Agent: {agent}
|
||||
## Time: {datetime.now().isoformat()}
|
||||
|
||||
## Output
|
||||
{output}
|
||||
|
||||
## Status
|
||||
{'COMPLETE' if result.returncode == 0 else 'IN_PROGRESS'}
|
||||
""")
|
||||
return result.returncode == 0
|
||||
|
||||
except FileNotFoundError:
|
||||
# Ralph not installed, use placeholder
|
||||
with open(iteration_file, "w") as f:
|
||||
f.write(f"""# Iteration {iteration}
|
||||
|
||||
## Agent: {agent}
|
||||
## Time: {datetime.now().isoformat()}
|
||||
|
||||
## Note
|
||||
Ralph Orchestrator not installed. Install with:
|
||||
pip install ralph-orchestrator
|
||||
|
||||
## Task Analysis
|
||||
{task}
|
||||
|
||||
## Next Steps
|
||||
1. Install Ralph Orchestrator
|
||||
2. Re-run ralphloop command
|
||||
""")
|
||||
return False
|
||||
except subprocess.TimeoutExpired:
|
||||
with open(iteration_file, "w") as f:
|
||||
f.write(f"""# Iteration {iteration}
|
||||
|
||||
## Agent: {agent}
|
||||
## Time: {datetime.now().isoformat()}
|
||||
|
||||
## Status: TIMEOUT
|
||||
|
||||
Iteration exceeded 300 second timeout.
|
||||
""")
|
||||
return False
|
||||
|
||||
|
||||
def run_ralph(task, agent, max_iterations, max_runtime):
|
||||
"""Run Ralph autonomous loop."""
|
||||
setup_ralph_directory()
|
||||
|
||||
state = load_state()
|
||||
if state["status"] == "completed":
|
||||
print(f"Task already completed at {state['completed_at']}")
|
||||
print(f"See {ITERATIONS_DIR / 'final.md'} for results")
|
||||
return
|
||||
|
||||
# Initialize
|
||||
state["status"] = "running"
|
||||
state["started_at"] = datetime.now().isoformat()
|
||||
save_state(state)
|
||||
|
||||
create_prompt(task, agent, max_iterations, max_runtime)
|
||||
create_config(agent, max_iterations, max_runtime)
|
||||
|
||||
start_time = datetime.now()
|
||||
completed = False
|
||||
|
||||
for iteration in range(1, max_iterations + 1):
|
||||
# Check runtime
|
||||
elapsed = (datetime.now() - start_time).total_seconds()
|
||||
if elapsed > max_runtime:
|
||||
print(f"Max runtime ({max_runtime}s) exceeded")
|
||||
break
|
||||
|
||||
if VERBOSE:
|
||||
print(f"[Ralph] Iteration {iteration}/{max_iterations}")
|
||||
|
||||
state["iteration"] = iteration
|
||||
save_state(state)
|
||||
|
||||
# Run iteration
|
||||
if run_ralph_iteration(task, iteration, agent):
|
||||
completed = True
|
||||
break
|
||||
|
||||
# Finalize
|
||||
state["status"] = "completed" if completed else "max_iterations_reached"
|
||||
state["completed_at"] = datetime.now().isoformat()
|
||||
save_state(state)
|
||||
|
||||
# Create final output
|
||||
final_file = ITERATIONS_DIR / "final.md"
|
||||
with open(final_file, "w") as f:
|
||||
f.write(f"""# RalphLoop Final Result
|
||||
|
||||
## Task
|
||||
{task}
|
||||
|
||||
## Agent: {agent}
|
||||
## Iterations: {state['iteration']}
|
||||
## Status: {state['status']}
|
||||
## Started: {state['started_at']}
|
||||
## Completed: {state['completed_at']}
|
||||
|
||||
## Result
|
||||
{'Task completed successfully!' if completed else 'Max iterations reached. Manual review needed.'}
|
||||
|
||||
## Output Files
|
||||
- iterations/001.md through iterations/{iteration:03d}.md
|
||||
- state.json - Progress tracking
|
||||
- ralph.yml - Configuration
|
||||
|
||||
## Next Steps
|
||||
{'Implement the solution from the final iteration.' if completed else 'Review iterations and continue manually or increase max_iterations.'}
|
||||
""")
|
||||
|
||||
print(f"\n[Ralph] {state['status'].upper()}")
|
||||
print(f"[Ralph] Iterations: {state['iteration']}/{max_iterations}")
|
||||
print(f"[Ralph] Output: {final_file}")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="RalphLoop - Ralph Orchestrator Wrapper",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=__doc__
|
||||
)
|
||||
parser.add_argument("task", help="Task description")
|
||||
parser.add_argument("--agent", default=DEFAULT_AGENT, help="Agent to use")
|
||||
parser.add_argument("--max-iterations", type=int, default=DEFAULT_MAX_ITERATIONS)
|
||||
parser.add_argument("--max-runtime", type=int, default=DEFAULT_MAX_RUNTIME)
|
||||
parser.add_argument("--verbose", action="store_true")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.verbose:
|
||||
global VERBOSE
|
||||
VERBOSE = True
|
||||
|
||||
run_ralph(
|
||||
task=args.task,
|
||||
agent=args.agent,
|
||||
max_iterations=args.max_iterations,
|
||||
max_runtime=args.max_runtime
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user