From 6d64be9b01660021c1d18ade367333718c3fa1a5 Mon Sep 17 00:00:00 2001 From: frankbria Date: Wed, 27 Aug 2025 09:39:43 -0700 Subject: [PATCH] Transform Ralph into global command system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major architectural change to make Ralph available as global commands: 🌟 New Global Installation System: - Add install.sh script for global installation to ~/.local/bin - Creates ralph, ralph-monitor, ralph-setup global commands - Installs templates and scripts to ~/.ralph/ directory - Automatic dependency checking and PATH configuration 🚀 Enhanced User Experience: - ralph-setup my-project (run from anywhere, no directory constraints) - ralph --monitor (start from any project directory) - ralph-monitor (global monitoring command) - No more ../ralph_loop.sh relative path requirements 🔧 Improved Architecture: - Global template system in ~/.ralph/templates/ - Smart path detection (global commands vs local scripts) - Maintains backward compatibility during transition - Clean separation of installation vs project files 📚 Updated Documentation: - All examples now use global commands (ralph vs ../ralph_loop.sh) - Clear installation instructions with ./install.sh - Global command reference in CLAUDE.md - Streamlined Quick Start workflow This makes Ralph much more professional and user-friendly by eliminating directory structure requirements and providing standard Unix command experience. --- CLAUDE.md | 38 ++++--- README.md | 39 +++---- install.sh | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++ ralph_loop.sh | 16 ++- 4 files changed, 332 insertions(+), 36 deletions(-) create mode 100755 install.sh diff --git a/CLAUDE.md b/CLAUDE.md index abb040c..00f7386 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -17,47 +17,50 @@ The system consists of four main bash scripts that work together: ## Key Commands +### Installation +```bash +# Install Ralph globally (run once) +./install.sh + +# Uninstall Ralph +./install.sh uninstall +``` + ### Setting Up a New Project ```bash -# Create a new Ralph-managed project -./setup.sh my-project-name +# Create a new Ralph-managed project (run from anywhere) +ralph-setup my-project-name cd my-project-name ``` ### Running the Ralph Loop ```bash # Start with integrated tmux monitoring (recommended) -../ralph_loop.sh --monitor +ralph --monitor # Start without monitoring -../ralph_loop.sh +ralph # With custom parameters and monitoring -../ralph_loop.sh --monitor --calls 50 --prompt my_custom_prompt.md +ralph --monitor --calls 50 --prompt my_custom_prompt.md # Check current status -../ralph_loop.sh --status +ralph --status ``` ### Monitoring ```bash # Integrated tmux monitoring (recommended) -../ralph_loop.sh --monitor +ralph --monitor # Manual monitoring in separate terminal -../ralph_monitor.sh +ralph-monitor # tmux session management tmux list-sessions tmux attach -t ``` -### System Setup -```bash -# Bootstrap the entire Ralph system (run once) -./create_files.sh -``` - ## Ralph Loop Configuration The loop is controlled by several key files and environment variables: @@ -109,6 +112,13 @@ Templates in `templates/` provide starting points for new projects: - `logs/` contains timestamped execution logs - `docs/generated/` for Ralph-created documentation +## Global Installation + +Ralph installs to: +- **Commands**: `~/.local/bin/` (ralph, ralph-monitor, ralph-setup) +- **Templates**: `~/.ralph/templates/` +- **Scripts**: `~/.ralph/` (ralph_loop.sh, ralph_monitor.sh, setup.sh) + ## Integration Points Ralph integrates with: diff --git a/README.md b/README.md index d92beef..d5cf76e 100644 --- a/README.md +++ b/README.md @@ -16,18 +16,19 @@ Ralph is an implementation of the [Ralph technique](https://github.com/paul-gaut ## 🚀 Quick Start -### 1. Clone and Setup +### 1. Install Ralph Globally ```bash git clone https://github.com/frankbria/ralph-claude-code.git cd ralph-claude-code -./create_files.sh +./install.sh ``` ### 2. Create Your First Project ```bash -./setup.sh my-awesome-project +# Run from anywhere - no need to be in specific directory +ralph-setup my-awesome-project cd my-awesome-project ``` @@ -42,11 +43,11 @@ Edit the generated files: ```bash # Recommended: Start with integrated tmux monitoring (requires tmux) -../ralph_loop.sh --monitor +ralph --monitor # Alternative: Manual monitoring (two separate terminals) -../ralph_loop.sh # Terminal 1: Ralph loop -../ralph_monitor.sh # Terminal 2: Live monitor +ralph # Terminal 1: Ralph loop +ralph-monitor # Terminal 2: Live monitor ``` ## 📖 How It Works @@ -73,28 +74,28 @@ Ralph automatically stops when it detects: ```bash # Default: 100 calls per hour -../ralph_loop.sh --calls 50 +ralph --calls 50 # With integrated monitoring -../ralph_loop.sh --monitor --calls 50 +ralph --monitor --calls 50 # Check current usage -../ralph_loop.sh --status +ralph --status ``` ### Custom Prompts ```bash # Use custom prompt file -../ralph_loop.sh --prompt my_custom_instructions.md +ralph --prompt my_custom_instructions.md # With integrated monitoring -../ralph_loop.sh --monitor --prompt my_custom_instructions.md +ralph --monitor --prompt my_custom_instructions.md ``` ### Exit Thresholds -Modify these variables in `ralph_loop.sh`: +Modify these variables in `~/.ralph/ralph_loop.sh`: ```bash MAX_CONSECUTIVE_TEST_LOOPS=3 # Exit after 3 test-only loops MAX_CONSECUTIVE_DONE_SIGNALS=2 # Exit after 2 "done" signals @@ -136,8 +137,8 @@ my-project/ ### Monitoring Progress -- Use `../ralph_monitor.sh` for live status updates -- Check logs in `logs/` for detailed execution history +- Use `ralph-monitor` for live status updates +- Check logs in `logs/` for detailed execution history - Monitor `status.json` for programmatic access - Watch for exit condition signals @@ -169,10 +170,10 @@ sudo yum install tmux ```bash # Integrated tmux monitoring (recommended) -../ralph_loop.sh --monitor +ralph --monitor # Manual monitoring in separate terminal -../ralph_monitor.sh +ralph-monitor ``` Shows real-time: @@ -191,7 +192,7 @@ Shows real-time: ```bash # JSON status output -../ralph_loop.sh --status +ralph --status # Manual log inspection tail -f logs/ralph.log @@ -210,7 +211,7 @@ tail -f logs/ralph.log 1. Fork the repository 2. Create a feature branch (`git checkout -b feature/amazing-feature`) 3. Make your changes -4. Test with `./create_files.sh` and sample projects +4. Test with `./install.sh` and sample projects 5. Commit your changes (`git commit -m 'Add amazing feature'`) 6. Push to the branch (`git push origin feature/amazing-feature`) 7. Open a Pull Request @@ -232,4 +233,4 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file --- -**Ready to let AI build your project?** Start with `./create_files.sh` and let Ralph take it from there! 🚀 \ No newline at end of file +**Ready to let AI build your project?** Start with `./install.sh` and let Ralph take it from there! 🚀 \ No newline at end of file diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..42e575d --- /dev/null +++ b/install.sh @@ -0,0 +1,275 @@ +#!/bin/bash + +# Ralph for Claude Code - Global Installation Script +set -e + +# Configuration +INSTALL_DIR="$HOME/.local/bin" +RALPH_HOME="$HOME/.ralph" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +log() { + local level=$1 + local message=$2 + local color="" + + case $level in + "INFO") color=$BLUE ;; + "WARN") color=$YELLOW ;; + "ERROR") color=$RED ;; + "SUCCESS") color=$GREEN ;; + esac + + echo -e "${color}[$(date '+%H:%M:%S')] [$level] $message${NC}" +} + +# Check dependencies +check_dependencies() { + log "INFO" "Checking dependencies..." + + local missing_deps=() + + if ! command -v node &> /dev/null && ! command -v npx &> /dev/null; then + missing_deps+=("Node.js/npm") + fi + + if ! command -v jq &> /dev/null; then + missing_deps+=("jq") + fi + + if ! command -v git &> /dev/null; then + missing_deps+=("git") + fi + + if [ ${#missing_deps[@]} -ne 0 ]; then + log "ERROR" "Missing required dependencies: ${missing_deps[*]}" + echo "Please install the missing dependencies:" + echo " Ubuntu/Debian: sudo apt-get install nodejs npm jq git" + echo " macOS: brew install node jq git" + echo " CentOS/RHEL: sudo yum install nodejs npm jq git" + exit 1 + fi + + # Check Claude Code CLI + if ! npx @anthropic/claude-code --version &> /dev/null; then + log "WARN" "Claude Code CLI not found. It will be downloaded when first used." + fi + + # Check tmux (optional) + if ! command -v tmux &> /dev/null; then + log "WARN" "tmux not found. Install for integrated monitoring: apt-get install tmux / brew install tmux" + fi + + log "SUCCESS" "Dependencies check completed" +} + +# Create installation directory +create_install_dirs() { + log "INFO" "Creating installation directories..." + + mkdir -p "$INSTALL_DIR" + mkdir -p "$RALPH_HOME" + mkdir -p "$RALPH_HOME/templates" + + log "SUCCESS" "Directories created: $INSTALL_DIR, $RALPH_HOME" +} + +# Install Ralph scripts +install_scripts() { + log "INFO" "Installing Ralph scripts..." + + # Copy templates to Ralph home + cp -r "$SCRIPT_DIR/templates/"* "$RALPH_HOME/templates/" + + # Create the main ralph command + cat > "$INSTALL_DIR/ralph" << 'EOF' +#!/bin/bash +# Ralph for Claude Code - Main Command + +RALPH_HOME="$HOME/.ralph" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Source the actual ralph loop script with global paths +exec "$RALPH_HOME/ralph_loop.sh" "$@" +EOF + + # Create ralph-monitor command + cat > "$INSTALL_DIR/ralph-monitor" << 'EOF' +#!/bin/bash +# Ralph Monitor - Global Command + +RALPH_HOME="$HOME/.ralph" + +exec "$RALPH_HOME/ralph_monitor.sh" "$@" +EOF + + # Create ralph-setup command + cat > "$INSTALL_DIR/ralph-setup" << 'EOF' +#!/bin/bash +# Ralph Project Setup - Global Command + +RALPH_HOME="$HOME/.ralph" + +exec "$RALPH_HOME/setup.sh" "$@" +EOF + + # Copy actual script files to Ralph home with modifications for global operation + cp "$SCRIPT_DIR/ralph_monitor.sh" "$RALPH_HOME/" + + # Make all commands executable + chmod +x "$INSTALL_DIR/ralph" + chmod +x "$INSTALL_DIR/ralph-monitor" + chmod +x "$INSTALL_DIR/ralph-setup" + chmod +x "$RALPH_HOME/ralph_monitor.sh" + + log "SUCCESS" "Ralph scripts installed to $INSTALL_DIR" +} + +# Install global ralph_loop.sh +install_ralph_loop() { + log "INFO" "Installing global ralph_loop.sh..." + + # Create modified ralph_loop.sh for global operation + sed \ + -e "s|RALPH_HOME=\"\$HOME/.ralph\"|RALPH_HOME=\"\$HOME/.ralph\"|g" \ + -e "s|\$script_dir/ralph_monitor.sh|\$RALPH_HOME/ralph_monitor.sh|g" \ + -e "s|\$script_dir/ralph_loop.sh|\$RALPH_HOME/ralph_loop.sh|g" \ + "$SCRIPT_DIR/ralph_loop.sh" > "$RALPH_HOME/ralph_loop.sh" + + chmod +x "$RALPH_HOME/ralph_loop.sh" + + log "SUCCESS" "Global ralph_loop.sh installed" +} + +# Install global setup.sh +install_setup() { + log "INFO" "Installing global setup script..." + + # Create modified setup.sh for global operation + cat > "$RALPH_HOME/setup.sh" << 'EOF' +#!/bin/bash + +# Ralph Project Setup Script - Global Version +set -e + +PROJECT_NAME=${1:-"my-project"} +RALPH_HOME="$HOME/.ralph" + +echo "🚀 Setting up Ralph project: $PROJECT_NAME" + +# Create project directory in current location +mkdir -p "$PROJECT_NAME" +cd "$PROJECT_NAME" + +# Create structure +mkdir -p {specs/stdlib,src,examples,logs,docs/generated} + +# Copy templates from Ralph home +cp "$RALPH_HOME/templates/PROMPT.md" . +cp "$RALPH_HOME/templates/fix_plan.md" @fix_plan.md +cp "$RALPH_HOME/templates/AGENT.md" @AGENT.md +cp -r "$RALPH_HOME/templates/specs/"* specs/ 2>/dev/null || true + +# Initialize git +git init +echo "# $PROJECT_NAME" > README.md +git add . +git commit -m "Initial Ralph project setup" + +echo "✅ Project $PROJECT_NAME created!" +echo "Next steps:" +echo " 1. Edit PROMPT.md with your project requirements" +echo " 2. Update specs/ with your project specifications" +echo " 3. Run: ralph --monitor" +echo " 4. Monitor: ralph-monitor (if running manually)" +EOF + + chmod +x "$RALPH_HOME/setup.sh" + + log "SUCCESS" "Global setup script installed" +} + +# Check PATH +check_path() { + log "INFO" "Checking PATH configuration..." + + if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then + log "WARN" "$INSTALL_DIR is not in your PATH" + echo "" + echo "Add this to your ~/.bashrc, ~/.zshrc, or ~/.profile:" + echo " export PATH=\"\$HOME/.local/bin:\$PATH\"" + echo "" + echo "Then run: source ~/.bashrc (or restart your terminal)" + echo "" + else + log "SUCCESS" "$INSTALL_DIR is already in PATH" + fi +} + +# Main installation +main() { + echo "🚀 Installing Ralph for Claude Code globally..." + echo "" + + check_dependencies + create_install_dirs + install_scripts + install_ralph_loop + install_setup + check_path + + echo "" + log "SUCCESS" "🎉 Ralph for Claude Code installed successfully!" + echo "" + echo "Global commands available:" + echo " ralph --monitor # Start Ralph with integrated monitoring" + echo " ralph --help # Show Ralph options" + echo " ralph-setup my-project # Create new Ralph project" + echo " ralph-monitor # Manual monitoring dashboard" + echo "" + echo "Quick start:" + echo " 1. ralph-setup my-awesome-project" + echo " 2. cd my-awesome-project" + echo " 3. # Edit PROMPT.md with your requirements" + echo " 4. ralph --monitor" + echo "" + + if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then + echo "⚠️ Don't forget to add $INSTALL_DIR to your PATH (see above)" + fi +} + +# Handle command line arguments +case "${1:-install}" in + install) + main + ;; + uninstall) + log "INFO" "Uninstalling Ralph for Claude Code..." + rm -f "$INSTALL_DIR/ralph" "$INSTALL_DIR/ralph-monitor" "$INSTALL_DIR/ralph-setup" + rm -rf "$RALPH_HOME" + log "SUCCESS" "Ralph for Claude Code uninstalled" + ;; + --help|-h) + echo "Ralph for Claude Code Installation" + echo "" + echo "Usage: $0 [install|uninstall]" + echo "" + echo "Commands:" + echo " install Install Ralph globally (default)" + echo " uninstall Remove Ralph installation" + echo " --help Show this help" + ;; + *) + echo "Unknown command: $1" + echo "Use --help for usage information" + exit 1 + ;; +esac \ No newline at end of file diff --git a/ralph_loop.sh b/ralph_loop.sh index e37a970..bf9efc0 100755 --- a/ralph_loop.sh +++ b/ralph_loop.sh @@ -49,7 +49,7 @@ check_tmux_available() { # Setup tmux session with monitor setup_tmux_session() { local session_name="ralph-$(date +%s)" - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + local ralph_home="${RALPH_HOME:-$HOME/.ralph}" log_status "INFO" "Setting up tmux session: $session_name" @@ -60,10 +60,20 @@ setup_tmux_session() { tmux split-window -h -t "$session_name" -c "$(pwd)" # Start monitor in the right pane - tmux send-keys -t "$session_name:0.1" "'$script_dir/ralph_monitor.sh'" Enter + if command -v ralph-monitor &> /dev/null; then + tmux send-keys -t "$session_name:0.1" "ralph-monitor" Enter + else + tmux send-keys -t "$session_name:0.1" "'$ralph_home/ralph_monitor.sh'" Enter + fi # Start ralph loop in the left pane (exclude tmux flag to avoid recursion) - local ralph_cmd="'$script_dir/ralph_loop.sh'" + local ralph_cmd + if command -v ralph &> /dev/null; then + ralph_cmd="ralph" + else + ralph_cmd="'$ralph_home/ralph_loop.sh'" + fi + if [[ "$MAX_CALLS_PER_HOUR" != "100" ]]; then ralph_cmd="$ralph_cmd --calls $MAX_CALLS_PER_HOUR" fi