Skip to content

decocms/ralph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ralph - Autonomous Claude Code Runner for GitHub Issues

Ralph is a Kubernetes-native tool that runs Claude Code autonomously to implement solutions for GitHub issues. Pass it a repo, issue number, and branch name — Claude will read the issue context and work until the task is complete.

Release

Features

  • GitHub Issue Integration — Fetches issue title, description, labels, and comments
  • Autonomous Loop — Runs Claude Code iteratively until completion signal
  • Smart Fork Detection — Automatically forks repos when no write access, pushes directly when allowed
  • Automatic PR Creation — Opens pull requests with proper issue references
  • Cost Tracking — Reports token usage and estimated costs at completion
  • Issue Commenting — Posts summary with PR link and cost to the original issue
  • Cross-Repo Issues — Fetch issues from one repo, implement in another
  • Safety Limits — Max iterations and rate limiting prevent runaway costs
  • Kubernetes Native — Helm chart for easy deployment
  • SSH Authentication — Secure Git operations with SSH keys

Quick Start

Prerequisites

  • Kubernetes cluster with kubectl configured
  • Helm installed
  • GitHub Personal Access Token
  • Anthropic API Key
  • SSH key for Git push access

1. Install the Helm Chart

# Add the chart repository (or clone this repo)
git clone https://github.com/decocms/ralph.git
cd ralph

2. Create Secrets

# Create namespace
kubectl create namespace ralph

# Create API secrets
kubectl create secret generic ralph-secrets \
  --from-literal=github-token='ghp_xxxxxxxxxxxx' \
  --from-literal=anthropic-api-key='sk-ant-xxxxxxxxxxxx' \
  -n ralph

# Create SSH key secret
kubectl create secret generic ralph-ssh-key \
  --from-file=ssh-private-key=$HOME/.ssh/id_rsa \
  -n ralph

3. Run a Job

# Using the CLI script
NAMESPACE=ralph ./ralph.sh git@github.com:owner/repo.git 42 fix/issue-42

# Or directly with Helm
helm install my-job ./charts/ralph \
  --set job.repo="git@github.com:owner/repo.git" \
  --set job.issueId="42" \
  --set job.branch="fix/issue-42" \
  --namespace ralph

Usage

CLI Script

./ralph.sh <target-repo> <issue> <branch-name>

The <issue> can be:

  • A number (e.g., 226) — fetches from target repo
  • A full GitHub URL (e.g., https://github.com/org/repo/issues/42) — fetches from that repo

Examples

# Issue from same repo
./ralph.sh git@github.com:acme/api.git 42 fix/issue-42

# Issue from different repo (cross-repo)
./ralph.sh git@github.com:acme/api.git https://github.com/acme/tasks/issues/123 fix/task-123

Environment Variables

Variable Default Description
NAMESPACE default Kubernetes namespace
CHART_PATH ./charts/ralph Path to Helm chart
IMAGE_REPO ghcr.io/decocms/ralph Container image
IMAGE_TAG latest Image tag

Helm Chart

Installation

helm install ralph-job ./charts/ralph \
  --set job.repo="git@github.com:owner/repo.git" \
  --set job.issueId="42" \
  --set job.branch="fix/issue-42" \
  --namespace ralph

Values

Parameter Description Default
job.repo Target repository URL (required) ""
job.issueId GitHub issue ID (required) ""
job.branch Branch name (required) ""
job.issueSource Cross-repo issue source ""
image.repository Container image ghcr.io/decocms/ralph
image.tag Image tag latest
claude.maxIterations Max loop iterations 10
claude.iterationDelay Delay between iterations 5
workflow.createPullRequest Create PR after push true
workflow.postIssueComment Post summary comment on issue true
secrets.apiSecretName Name of API keys secret ralph-secrets
secrets.sshSecretName Name of SSH key secret ralph-ssh-key

See charts/ralph/values.yaml for all options.

How It Works

┌─────────────────────────────────────────────────────────────┐
│                         Ralph Flow                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ./ralph.sh <repo> <issue> <branch>                        │
│     │                                                       │
│     ▼                                                       │
│  1. Helm install → Creates K8s Job                         │
│                                                             │
│  Inside the container:                                      │
│  ┌────────────────────────────────────────────────────────┐│
│  │ 2. Fetch issue context from GitHub API                 ││
│  │ 3. Check write access → Fork if needed                 ││
│  │ 4. Clone repo (or fork) & create branch                ││
│  │ 5. Run Claude Code loop until :::TASK_COMPLETE:::      ││
│  │ 6. Commit & push changes                               ││
│  │ 7. Create Pull Request (via gh CLI)                    ││
│  │ 8. Post cost summary comment on issue                  ││
│  └────────────────────────────────────────────────────────┘│
│                                                             │
│  Result: PR opened and issue updated with summary           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Fork Workflow

Ralph automatically detects if you have write access to the target repository:

  1. Write access exists → Pushes directly to the repo, creates PR within same repo
  2. No write access → Creates a fork, pushes to fork, creates PR from fork to upstream

This allows Ralph to work on any public repository without requiring collaborator access.

Cost Tracking

Ralph tracks token usage across all Claude iterations and reports:

  • Input tokens — Tokens sent to Claude
  • Output tokens — Tokens generated by Claude
  • Estimated cost — Based on Claude Sonnet 3.5 pricing

At the end of each run, Ralph:

  1. Prints a cost summary to the logs
  2. Posts a comment on the GitHub issue with the cost breakdown

Example output:

================================================================================
                           RALPH COST REPORT
================================================================================

Token Usage:
  - Input tokens:  15234
  - Output tokens: 8921
  - Total tokens:  24155

Estimated Cost (Claude Sonnet 3.5 pricing):
  - Input cost:    $0.0457
  - Output cost:   $0.1338
  - TOTAL COST:    $0.1795

================================================================================

The Ralph Wiggum Technique

This project implements the Ralph Wiggum AI Loop Technique — an iterative AI development methodology where a simple loop repeatedly feeds Claude a prompt until a completion marker is detected.

# The core concept:
while :; do cat PROMPT.md | claude ; done

Key principles:

  • Iteration > Perfection — Don't aim for perfect on first try
  • Failures Are Data — Failures are predictable and informative
  • Persistence Wins — Keep trying until success

File Structure

.
├── ralph.sh              # CLI tool - creates K8s jobs via Helm
├── entrypoint.sh         # Container entrypoint (runs inside pod)
├── Dockerfile            # Container image definition
├── charts/
│   └── ralph/            # Helm chart
│       ├── Chart.yaml
│       ├── values.yaml
│       └── templates/
├── .github/
│   └── workflows/
│       └── release.yaml  # CI/CD - publishes to GHCR on tags
└── README.md

CI/CD

The project uses GitHub Actions to automatically build and publish:

  • Docker imageghcr.io/decocms/ralph:TAG
  • Helm chart → GitHub Release assets

Creating a Release

git tag v1.0.0
git push origin v1.0.0

This triggers the workflow to:

  1. Build multi-arch Docker image (amd64, arm64)
  2. Push to GitHub Container Registry
  3. Package and upload Helm chart

Security

  • Secrets: Never committed to Git - use Kubernetes secrets
  • Non-root: Container runs as node user (UID 1000)
  • Isolation: Each job runs in its own pod
  • TTL: Jobs auto-delete after 1 hour

Required GitHub Token Permissions

The PAT needs sufficient permissions for forking, pushing, and creating PRs:

  • Public repos: public_repo, read:org (for forking)
  • Private repos: repo (full control)

Fine-grained token scopes (recommended):

  • contents: write — Push commits
  • pull_requests: write — Create PRs
  • issues: write — Post comments
  • metadata: read — Read repo info

Troubleshooting

Check Job Status

kubectl get jobs -n ralph -l app.kubernetes.io/name=ralph
kubectl logs -f job/ralph-issue-42 -n ralph

Delete a Job

helm uninstall ralph-issue-42 -n ralph

SSH Key Issues

# Verify secret exists
kubectl get secret ralph-ssh-key -n ralph

# Check key format
kubectl get secret ralph-ssh-key -n ralph -o jsonpath='{.data.ssh-private-key}' | base64 -d | head -2

License

MIT License

Credits

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages