Transform Ralph into global command system

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.
This commit is contained in:
frankbria 2025-08-27 09:39:43 -07:00
parent d81519584f
commit 6d64be9b01
4 changed files with 332 additions and 36 deletions

View file

@ -17,47 +17,50 @@ The system consists of four main bash scripts that work together:
## Key Commands ## Key Commands
### Installation
```bash
# Install Ralph globally (run once)
./install.sh
# Uninstall Ralph
./install.sh uninstall
```
### Setting Up a New Project ### Setting Up a New Project
```bash ```bash
# Create a new Ralph-managed project # Create a new Ralph-managed project (run from anywhere)
./setup.sh my-project-name ralph-setup my-project-name
cd my-project-name cd my-project-name
``` ```
### Running the Ralph Loop ### Running the Ralph Loop
```bash ```bash
# Start with integrated tmux monitoring (recommended) # Start with integrated tmux monitoring (recommended)
../ralph_loop.sh --monitor ralph --monitor
# Start without monitoring # Start without monitoring
../ralph_loop.sh ralph
# With custom parameters and monitoring # 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 # Check current status
../ralph_loop.sh --status ralph --status
``` ```
### Monitoring ### Monitoring
```bash ```bash
# Integrated tmux monitoring (recommended) # Integrated tmux monitoring (recommended)
../ralph_loop.sh --monitor ralph --monitor
# Manual monitoring in separate terminal # Manual monitoring in separate terminal
../ralph_monitor.sh ralph-monitor
# tmux session management # tmux session management
tmux list-sessions tmux list-sessions
tmux attach -t <session-name> tmux attach -t <session-name>
``` ```
### System Setup
```bash
# Bootstrap the entire Ralph system (run once)
./create_files.sh
```
## Ralph Loop Configuration ## Ralph Loop Configuration
The loop is controlled by several key files and environment variables: 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 - `logs/` contains timestamped execution logs
- `docs/generated/` for Ralph-created documentation - `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 ## Integration Points
Ralph integrates with: Ralph integrates with:

View file

@ -16,18 +16,19 @@ Ralph is an implementation of the [Ralph technique](https://github.com/paul-gaut
## 🚀 Quick Start ## 🚀 Quick Start
### 1. Clone and Setup ### 1. Install Ralph Globally
```bash ```bash
git clone https://github.com/frankbria/ralph-claude-code.git git clone https://github.com/frankbria/ralph-claude-code.git
cd ralph-claude-code cd ralph-claude-code
./create_files.sh ./install.sh
``` ```
### 2. Create Your First Project ### 2. Create Your First Project
```bash ```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 cd my-awesome-project
``` ```
@ -42,11 +43,11 @@ Edit the generated files:
```bash ```bash
# Recommended: Start with integrated tmux monitoring (requires tmux) # Recommended: Start with integrated tmux monitoring (requires tmux)
../ralph_loop.sh --monitor ralph --monitor
# Alternative: Manual monitoring (two separate terminals) # Alternative: Manual monitoring (two separate terminals)
../ralph_loop.sh # Terminal 1: Ralph loop ralph # Terminal 1: Ralph loop
../ralph_monitor.sh # Terminal 2: Live monitor ralph-monitor # Terminal 2: Live monitor
``` ```
## 📖 How It Works ## 📖 How It Works
@ -73,28 +74,28 @@ Ralph automatically stops when it detects:
```bash ```bash
# Default: 100 calls per hour # Default: 100 calls per hour
../ralph_loop.sh --calls 50 ralph --calls 50
# With integrated monitoring # With integrated monitoring
../ralph_loop.sh --monitor --calls 50 ralph --monitor --calls 50
# Check current usage # Check current usage
../ralph_loop.sh --status ralph --status
``` ```
### Custom Prompts ### Custom Prompts
```bash ```bash
# Use custom prompt file # Use custom prompt file
../ralph_loop.sh --prompt my_custom_instructions.md ralph --prompt my_custom_instructions.md
# With integrated monitoring # With integrated monitoring
../ralph_loop.sh --monitor --prompt my_custom_instructions.md ralph --monitor --prompt my_custom_instructions.md
``` ```
### Exit Thresholds ### Exit Thresholds
Modify these variables in `ralph_loop.sh`: Modify these variables in `~/.ralph/ralph_loop.sh`:
```bash ```bash
MAX_CONSECUTIVE_TEST_LOOPS=3 # Exit after 3 test-only loops MAX_CONSECUTIVE_TEST_LOOPS=3 # Exit after 3 test-only loops
MAX_CONSECUTIVE_DONE_SIGNALS=2 # Exit after 2 "done" signals MAX_CONSECUTIVE_DONE_SIGNALS=2 # Exit after 2 "done" signals
@ -136,8 +137,8 @@ my-project/
### Monitoring Progress ### Monitoring Progress
- Use `../ralph_monitor.sh` for live status updates - Use `ralph-monitor` for live status updates
- Check logs in `logs/` for detailed execution history - Check logs in `logs/` for detailed execution history
- Monitor `status.json` for programmatic access - Monitor `status.json` for programmatic access
- Watch for exit condition signals - Watch for exit condition signals
@ -169,10 +170,10 @@ sudo yum install tmux
```bash ```bash
# Integrated tmux monitoring (recommended) # Integrated tmux monitoring (recommended)
../ralph_loop.sh --monitor ralph --monitor
# Manual monitoring in separate terminal # Manual monitoring in separate terminal
../ralph_monitor.sh ralph-monitor
``` ```
Shows real-time: Shows real-time:
@ -191,7 +192,7 @@ Shows real-time:
```bash ```bash
# JSON status output # JSON status output
../ralph_loop.sh --status ralph --status
# Manual log inspection # Manual log inspection
tail -f logs/ralph.log tail -f logs/ralph.log
@ -210,7 +211,7 @@ tail -f logs/ralph.log
1. Fork the repository 1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`) 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes 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'`) 5. Commit your changes (`git commit -m 'Add amazing feature'`)
6. Push to the branch (`git push origin feature/amazing-feature`) 6. Push to the branch (`git push origin feature/amazing-feature`)
7. Open a Pull Request 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! 🚀 **Ready to let AI build your project?** Start with `./install.sh` and let Ralph take it from there! 🚀

275
install.sh Executable file
View file

@ -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

View file

@ -49,7 +49,7 @@ check_tmux_available() {
# Setup tmux session with monitor # Setup tmux session with monitor
setup_tmux_session() { setup_tmux_session() {
local session_name="ralph-$(date +%s)" 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" 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)" tmux split-window -h -t "$session_name" -c "$(pwd)"
# Start monitor in the right pane # 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) # 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 if [[ "$MAX_CALLS_PER_HOUR" != "100" ]]; then
ralph_cmd="$ralph_cmd --calls $MAX_CALLS_PER_HOUR" ralph_cmd="$ralph_cmd --calls $MAX_CALLS_PER_HOUR"
fi fi