ralphblaster-agent 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +253 -0
- package/bin/ralph-agent.js +87 -0
- package/package.json +59 -0
- package/src/api-client.js +344 -0
- package/src/config.js +21 -0
- package/src/executor.js +1014 -0
- package/src/index.js +243 -0
- package/src/logger.js +96 -0
- package/src/ralph/prompt.md +165 -0
- package/src/ralph/ralph.sh +239 -0
- package/src/ralph-instance-manager.js +171 -0
- package/src/worktree-manager.js +170 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Wildfront LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# Ralph Agent
|
|
2
|
+
|
|
3
|
+
Ralph Agent is a distributed autonomous coding agent that polls a Rails API for jobs and executes them locally using Claude CLI.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔄 **Automatic Job Polling**: Continuously polls the Ralph API for new coding jobs
|
|
8
|
+
- 🤖 **Claude CLI Integration**: Executes jobs using the Claude CLI
|
|
9
|
+
- 💪 **Resilient**: Handles failures gracefully with automatic retries and timeouts
|
|
10
|
+
- 🔐 **Secure**: Uses API tokens with specific permissions for authentication
|
|
11
|
+
- 📊 **Real-time Updates**: Reports job progress and status back to the API
|
|
12
|
+
- ⚡ **Heartbeat System**: Keeps jobs alive during long-running executions
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
- Node.js >= 18.0.0
|
|
17
|
+
- Claude CLI installed and available in PATH (`claude --version` should work)
|
|
18
|
+
- A Ralph API token with `ralph_agent` permission
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
### Global Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g ralph-agent
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Local Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
git clone <repository>
|
|
32
|
+
cd ralph-agent
|
|
33
|
+
npm install
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Using npx (No Installation Required)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx ralph-agent --token=your_token_here
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
### Basic Usage
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Production (default)
|
|
48
|
+
ralph-agent --token=your_api_token_here
|
|
49
|
+
|
|
50
|
+
# Using environment variable
|
|
51
|
+
RALPH_API_TOKEN=your_api_token_here ralph-agent
|
|
52
|
+
|
|
53
|
+
# Local development (override API URL)
|
|
54
|
+
ralph-agent --token=your_token --api-url=http://localhost:5002
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Configuration Options
|
|
58
|
+
|
|
59
|
+
The agent can be configured via environment variables or command-line flags:
|
|
60
|
+
|
|
61
|
+
| Environment Variable | CLI Flag | Default | Description |
|
|
62
|
+
|---------------------|----------|---------|-------------|
|
|
63
|
+
| `RALPH_API_TOKEN` | `--token=` | *Required* | API authentication token |
|
|
64
|
+
| `RALPH_API_URL` | `--api-url=` | `https://ralphblaster.com` | Ralph API base URL |
|
|
65
|
+
| `RALPH_POLL_INTERVAL` | - | `5000` | Polling interval in milliseconds |
|
|
66
|
+
| `RALPH_LOG_LEVEL` | - | `info` | Log level (error, warn, info, debug) |
|
|
67
|
+
| `RALPH_MAX_RETRIES` | - | `3` | Maximum retry attempts |
|
|
68
|
+
|
|
69
|
+
### Using .env File
|
|
70
|
+
|
|
71
|
+
Create a `.env` file in the ralph-agent directory:
|
|
72
|
+
|
|
73
|
+
```env
|
|
74
|
+
RALPH_API_TOKEN=your_api_token_here
|
|
75
|
+
# RALPH_API_URL=http://localhost:5002 # Uncomment for local development
|
|
76
|
+
RALPH_POLL_INTERVAL=5000
|
|
77
|
+
RALPH_LOG_LEVEL=info
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Then run:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
ralph-agent
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## How It Works
|
|
87
|
+
|
|
88
|
+
1. **Polling**: The agent continuously polls the API endpoint `/api/v1/ralph/jobs/next` for available jobs
|
|
89
|
+
2. **Job Claiming**: When a job is found, it's automatically claimed by the agent
|
|
90
|
+
3. **Status Update**: The agent marks the job as "running" and starts sending heartbeats
|
|
91
|
+
4. **Execution**: The job is executed based on its type:
|
|
92
|
+
- **PRD Generation**: Uses Claude `/prd` skill or direct prompts
|
|
93
|
+
- **Code Execution**: Creates a Ralph autonomous agent instance (see below)
|
|
94
|
+
5. **Completion**: Results are parsed and reported back to the API
|
|
95
|
+
6. **Cleanup**: The agent marks the job as completed or failed and continues polling
|
|
96
|
+
|
|
97
|
+
## Ralph Autonomous Agent Integration
|
|
98
|
+
|
|
99
|
+
For `code_execution` job types, the agent uses the Ralph autonomous system - an iterative, PRD-driven execution framework that enables complex, multi-step implementations.
|
|
100
|
+
|
|
101
|
+
### How Ralph Works
|
|
102
|
+
|
|
103
|
+
1. **Worktree Creation**: Creates an isolated git worktree for the job
|
|
104
|
+
2. **Instance Setup**: Creates a `ralph-instance/` directory with:
|
|
105
|
+
- `prd.json` - Converted from the job prompt using Claude `/ralph` skill
|
|
106
|
+
- `ralph.sh` - The autonomous agent loop script
|
|
107
|
+
- `prompt.md` - Agent instructions
|
|
108
|
+
- `progress.txt` - Progress tracking log
|
|
109
|
+
3. **Iterative Execution**: Ralph runs up to 10 iterations, each:
|
|
110
|
+
- Reading the PRD and current progress
|
|
111
|
+
- Selecting the next highest-priority user story
|
|
112
|
+
- Implementing the story in the worktree
|
|
113
|
+
- Running quality checks (tests, typecheck, lint)
|
|
114
|
+
- Committing changes
|
|
115
|
+
- Updating the PRD to mark the story as complete
|
|
116
|
+
- Logging progress
|
|
117
|
+
4. **Completion Detection**: Ralph signals completion with `<promise>COMPLETE</promise>` when all stories pass
|
|
118
|
+
5. **Progress Reporting**: Real-time updates from `progress.txt` are sent back to the API
|
|
119
|
+
|
|
120
|
+
### Ralph Directory Structure
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
.ralph-worktrees/job-{id}/
|
|
124
|
+
├── ralph-instance/ # Ralph state directory
|
|
125
|
+
│ ├── ralph.sh # Execution loop
|
|
126
|
+
│ ├── prompt.md # Agent instructions
|
|
127
|
+
│ ├── prd.json # Generated PRD with user stories
|
|
128
|
+
│ ├── progress.txt # Progress log
|
|
129
|
+
│ └── .worktree-path # Worktree location reference
|
|
130
|
+
└── [project files...] # Isolated worktree content
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Environment Variables for Ralph
|
|
134
|
+
|
|
135
|
+
Ralph execution uses these environment variables:
|
|
136
|
+
|
|
137
|
+
- `RALPH_WORKTREE_PATH` - Path to the git worktree
|
|
138
|
+
- `RALPH_INSTANCE_DIR` - Path to the Ralph instance directory
|
|
139
|
+
- `RALPH_MAIN_REPO` - Path to the main repository
|
|
140
|
+
|
|
141
|
+
### Ralph Execution Limits
|
|
142
|
+
|
|
143
|
+
- **Max Iterations**: 10
|
|
144
|
+
- **Timeout**: 2 hours
|
|
145
|
+
- **Completion**: All user stories must pass quality checks
|
|
146
|
+
|
|
147
|
+
### Advantages of Ralph Integration
|
|
148
|
+
|
|
149
|
+
- **Structured Approach**: PRD-driven development ensures clear requirements
|
|
150
|
+
- **Quality Assurance**: Each story is validated with tests before proceeding
|
|
151
|
+
- **Progress Tracking**: Detailed logs of what was accomplished
|
|
152
|
+
- **Isolation**: Git worktrees keep work separate from main repository
|
|
153
|
+
- **Iterative Refinement**: Can fix issues and retry failed stories automatically
|
|
154
|
+
|
|
155
|
+
## API Token Setup
|
|
156
|
+
|
|
157
|
+
To create an API token with ralph_agent permission:
|
|
158
|
+
|
|
159
|
+
1. Log into your Ralph account
|
|
160
|
+
2. Navigate to API Tokens settings
|
|
161
|
+
3. Create a new token
|
|
162
|
+
4. Check the "Ralph Agent Access" permission
|
|
163
|
+
5. Copy the token (shown only once!)
|
|
164
|
+
|
|
165
|
+
## Example Output
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
[2026-01-16T20:00:00.000Z] [INFO]
|
|
169
|
+
╔═══════════════════════════════════════╗
|
|
170
|
+
║ Ralph Agent Starting... ║
|
|
171
|
+
╚═══════════════════════════════════════╝
|
|
172
|
+
|
|
173
|
+
[2026-01-16T20:00:00.123Z] [INFO] Ralph Agent starting...
|
|
174
|
+
[2026-01-16T20:00:00.124Z] [INFO] API URL: https://ralphblaster.com
|
|
175
|
+
[2026-01-16T20:00:00.125Z] [INFO] Poll interval: 5000ms
|
|
176
|
+
[2026-01-16T20:00:05.234Z] [INFO] Claimed job #42 - Implement user authentication
|
|
177
|
+
[2026-01-16T20:00:05.345Z] [INFO] Job #42 marked as running
|
|
178
|
+
[2026-01-16T20:00:05.456Z] [INFO] Executing job #42 in /path/to/project
|
|
179
|
+
[2026-01-16T20:05:30.789Z] [INFO] Job #42 marked as completed
|
|
180
|
+
[2026-01-16T20:05:30.890Z] [INFO] Job #42 completed successfully
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Graceful Shutdown
|
|
184
|
+
|
|
185
|
+
The agent handles shutdown signals gracefully:
|
|
186
|
+
|
|
187
|
+
- `SIGINT` (Ctrl+C): Marks current job as failed and exits
|
|
188
|
+
- `SIGTERM`: Same as SIGINT
|
|
189
|
+
- Uncaught exceptions: Logged and triggers shutdown
|
|
190
|
+
|
|
191
|
+
## Troubleshooting
|
|
192
|
+
|
|
193
|
+
### "API token requires 'ralph_agent' permission"
|
|
194
|
+
|
|
195
|
+
Your API token doesn't have the correct permissions. Create a new token with the `ralph_agent` permission checked.
|
|
196
|
+
|
|
197
|
+
### "Cannot connect to API"
|
|
198
|
+
|
|
199
|
+
Check that:
|
|
200
|
+
- The API URL is correct
|
|
201
|
+
- The Rails server is running
|
|
202
|
+
- There are no firewall issues
|
|
203
|
+
|
|
204
|
+
### "Failed to execute Claude CLI"
|
|
205
|
+
|
|
206
|
+
Ensure:
|
|
207
|
+
- Claude CLI is installed (`claude --version`)
|
|
208
|
+
- Claude CLI is in your PATH
|
|
209
|
+
- You're authenticated with Claude
|
|
210
|
+
|
|
211
|
+
### "Project path does not exist"
|
|
212
|
+
|
|
213
|
+
The project's `system_path` in Ralph is incorrect or the directory doesn't exist on your machine.
|
|
214
|
+
|
|
215
|
+
## Development
|
|
216
|
+
|
|
217
|
+
### Running Locally
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
npm start
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Debugging
|
|
224
|
+
|
|
225
|
+
Enable debug logging:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
RALPH_LOG_LEVEL=debug ralph-agent --token=your_token
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Architecture
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
┌─────────────────┐ ┌──────────────────┐
|
|
235
|
+
│ Ralph Agent │ │ Rails API │
|
|
236
|
+
│ │ │ │
|
|
237
|
+
│ ┌──────────┐ │ Poll │ ┌────────────┐ │
|
|
238
|
+
│ │ Polling │───┼────────>│ │ Job Queue │ │
|
|
239
|
+
│ │ Loop │ │ │ └────────────┘ │
|
|
240
|
+
│ └──────────┘ │ │ │
|
|
241
|
+
│ │ │ Claim │ │
|
|
242
|
+
│ ▼ │<────────┤ │
|
|
243
|
+
│ ┌──────────┐ │ │ │
|
|
244
|
+
│ │ Executor │ │ │ │
|
|
245
|
+
│ │ (Claude)│ │ Status │ │
|
|
246
|
+
│ └──────────┘ │────────>│ │
|
|
247
|
+
│ │ │ │
|
|
248
|
+
└─────────────────┘ └──────────────────┘
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
MIT
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Parse command line arguments BEFORE loading modules that use config
|
|
4
|
+
const args = process.argv.slice(2);
|
|
5
|
+
|
|
6
|
+
// Check for --token flag
|
|
7
|
+
const tokenIndex = args.findIndex(arg => arg.startsWith('--token='));
|
|
8
|
+
if (tokenIndex !== -1) {
|
|
9
|
+
const token = args[tokenIndex].split('=')[1];
|
|
10
|
+
if (!token || token.trim() === '') {
|
|
11
|
+
console.error('Error: --token flag requires a value');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
process.env.RALPH_API_TOKEN = token;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Check for --api-url flag
|
|
18
|
+
const apiUrlIndex = args.findIndex(arg => arg.startsWith('--api-url='));
|
|
19
|
+
if (apiUrlIndex !== -1) {
|
|
20
|
+
const apiUrl = args[apiUrlIndex].split('=')[1];
|
|
21
|
+
if (!apiUrl || apiUrl.trim() === '') {
|
|
22
|
+
console.error('Error: --api-url flag requires a value');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
process.env.RALPH_API_URL = apiUrl;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Show help
|
|
29
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
30
|
+
console.log(`
|
|
31
|
+
Ralph Agent - Autonomous coding agent for Ralph
|
|
32
|
+
|
|
33
|
+
Usage:
|
|
34
|
+
ralph-agent [options]
|
|
35
|
+
|
|
36
|
+
Options:
|
|
37
|
+
--token=<token> API token for authentication (required)
|
|
38
|
+
--api-url=<url> API base URL (default: https://ralphblaster.com)
|
|
39
|
+
--help, -h Show this help message
|
|
40
|
+
|
|
41
|
+
Environment Variables:
|
|
42
|
+
RALPH_API_TOKEN API token (required if not using --token)
|
|
43
|
+
RALPH_API_URL API base URL (default: https://ralphblaster.com)
|
|
44
|
+
RALPH_LOG_LEVEL Log level: error, warn, info, debug (default: info)
|
|
45
|
+
RALPH_ALLOWED_PATHS Colon-separated list of allowed base paths for projects
|
|
46
|
+
(optional security whitelist, e.g., /Users/me/projects:/home/me/work)
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
# Run with token from command line
|
|
50
|
+
ralph-agent --token=your_token_here
|
|
51
|
+
|
|
52
|
+
# Run with environment variable
|
|
53
|
+
RALPH_API_TOKEN=your_token_here ralph-agent
|
|
54
|
+
|
|
55
|
+
# Run with custom API URL
|
|
56
|
+
ralph-agent --token=your_token --api-url=http://localhost:3000
|
|
57
|
+
|
|
58
|
+
# Use npx
|
|
59
|
+
npx ralph-agent --token=your_token_here
|
|
60
|
+
`);
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Check for version
|
|
65
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
66
|
+
const packageJson = require('../package.json');
|
|
67
|
+
console.log(`ralph-agent v${packageJson.version}`);
|
|
68
|
+
process.exit(0);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Load modules AFTER environment variables are set
|
|
72
|
+
const RalphAgent = require('../src/index');
|
|
73
|
+
const logger = require('../src/logger');
|
|
74
|
+
|
|
75
|
+
// Start the agent
|
|
76
|
+
const agent = new RalphAgent();
|
|
77
|
+
|
|
78
|
+
logger.info('');
|
|
79
|
+
logger.info('╔═══════════════════════════════════════╗');
|
|
80
|
+
logger.info('║ Ralph Agent Starting... ║');
|
|
81
|
+
logger.info('╚═══════════════════════════════════════╝');
|
|
82
|
+
logger.info('');
|
|
83
|
+
|
|
84
|
+
agent.start().catch(error => {
|
|
85
|
+
logger.error('Fatal error starting agent', error);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ralphblaster-agent",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Ralph agent that polls for and executes coding jobs via Claude CLI",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"ralphblaster-agent": "bin/ralph-agent.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"src/",
|
|
12
|
+
"LICENSE",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"start": "node bin/ralph-agent.js",
|
|
17
|
+
"test": "jest",
|
|
18
|
+
"test:watch": "jest --watch",
|
|
19
|
+
"test:coverage": "jest --coverage"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"ralph",
|
|
23
|
+
"agent",
|
|
24
|
+
"claude",
|
|
25
|
+
"automation"
|
|
26
|
+
],
|
|
27
|
+
"author": "Wildfront LLC <m@wildfront.co>",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/Wildfront/ralphblaster-agent.git"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/Wildfront/ralphblaster-agent#readme",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/Wildfront/ralphblaster-agent/issues"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"axios": "^1.6.0",
|
|
39
|
+
"dotenv": "^16.3.1"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/jest": "^29.5.14",
|
|
43
|
+
"jest": "^29.7.0"
|
|
44
|
+
},
|
|
45
|
+
"jest": {
|
|
46
|
+
"testEnvironment": "node",
|
|
47
|
+
"coverageDirectory": "coverage",
|
|
48
|
+
"collectCoverageFrom": [
|
|
49
|
+
"src/**/*.js",
|
|
50
|
+
"!src/logger.js"
|
|
51
|
+
],
|
|
52
|
+
"testMatch": [
|
|
53
|
+
"**/test/**/*.test.js"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=18.0.0"
|
|
58
|
+
}
|
|
59
|
+
}
|