Coverage for mcp_bridge/tools/continuous_loop.py: 18%

33 statements  

« prev     ^ index     » next       coverage.py v7.10.1, created at 2026-01-10 00:20 -0500

1""" 

2Continuous Loop (Ralph Loop) for Stravinsky. 

3 

4Allows Stravinsky to operate in an autonomous loop until criteria are met. 

5""" 

6 

7import json 

8import logging 

9from pathlib import Path 

10 

11logger = logging.getLogger(__name__) 

12 

13async def enable_ralph_loop(goal: str, max_iterations: int = 10) -> str: 

14 """ 

15 Enable continuous processing until a goal is met. 

16  

17 Args: 

18 goal: The goal to achieve and verify. 

19 max_iterations: Maximum number of iterations before stopping. 

20 """ 

21 project_root = Path.cwd() 

22 settings_file = project_root / ".claude" / "settings.json" 

23 

24 settings = {} 

25 if settings_file.exists(): 

26 try: 

27 settings = json.loads(settings_file.read_text()) 

28 except: 

29 pass 

30 

31 if "hooks" not in settings: 

32 settings["hooks"] = {} 

33 

34 # Set the Stop hook to re-trigger if goal not met 

35 # Note: Stravinsky's prompt will handle the internal logic  

36 # but the presence of this hook signals "Continue" to Claude Code. 

37 settings["hooks"]["Stop"] = [ 

38 { 

39 "type": "command", 

40 "command": f'echo "Looping for goal: {goal}"', 

41 } 

42 ] 

43 

44 settings_file.parent.mkdir(parents=True, exist_ok=True) 

45 settings_file.write_text(json.dumps(settings, indent=2)) 

46 

47 return f"🔄 Ralph Loop ENABLED. Goal: {goal}. Stravinsky will now process continuously until completion." 

48 

49async def disable_ralph_loop() -> str: 

50 """Disable the autonomous loop.""" 

51 project_root = Path.cwd() 

52 settings_file = project_root / ".claude" / "settings.json" 

53 

54 if not settings_file.exists(): 

55 return "Ralph Loop is already disabled." 

56 

57 try: 

58 settings = json.loads(settings_file.read_text()) 

59 if "hooks" in settings and "Stop" in settings["hooks"]: 

60 del settings["hooks"]["Stop"] 

61 settings_file.write_text(json.dumps(settings, indent=2)) 

62 return "✅ Ralph Loop DISABLED." 

63 except: 

64 pass 

65 

66 return "Failed to disable Ralph Loop or it was not active."