ralphblaster-agent 0.1.1

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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +294 -0
  3. package/bin/agent-dashboard.sh +168 -0
  4. package/bin/monitor-agent.sh +264 -0
  5. package/bin/ralphblaster.js +247 -0
  6. package/package.json +64 -0
  7. package/postinstall-colored.js +66 -0
  8. package/src/api-client.js +764 -0
  9. package/src/claude-plugin/.claude-plugin/plugin.json +9 -0
  10. package/src/claude-plugin/README.md +42 -0
  11. package/src/claude-plugin/skills/ralph/SKILL.md +259 -0
  12. package/src/commands/add-project.js +257 -0
  13. package/src/commands/init.js +79 -0
  14. package/src/config-file-manager.js +84 -0
  15. package/src/config.js +66 -0
  16. package/src/error-window.js +86 -0
  17. package/src/executor/claude-runner.js +716 -0
  18. package/src/executor/error-handler.js +65 -0
  19. package/src/executor/git-helper.js +196 -0
  20. package/src/executor/index.js +296 -0
  21. package/src/executor/job-handlers/clarifying-questions.js +213 -0
  22. package/src/executor/job-handlers/code-execution.js +145 -0
  23. package/src/executor/job-handlers/prd-generation.js +259 -0
  24. package/src/executor/path-helper.js +74 -0
  25. package/src/executor/prompt-validator.js +51 -0
  26. package/src/executor.js +4 -0
  27. package/src/index.js +342 -0
  28. package/src/logger.js +193 -0
  29. package/src/logging/README.md +93 -0
  30. package/src/logging/config.js +179 -0
  31. package/src/logging/destinations/README.md +290 -0
  32. package/src/logging/destinations/api-destination-unbatched.js +118 -0
  33. package/src/logging/destinations/api-destination.js +40 -0
  34. package/src/logging/destinations/base-destination.js +85 -0
  35. package/src/logging/destinations/batched-destination.js +198 -0
  36. package/src/logging/destinations/console-destination.js +172 -0
  37. package/src/logging/destinations/file-destination.js +208 -0
  38. package/src/logging/destinations/index.js +29 -0
  39. package/src/logging/destinations/progress-batch-destination-unbatched.js +92 -0
  40. package/src/logging/destinations/progress-batch-destination.js +41 -0
  41. package/src/logging/formatter.js +288 -0
  42. package/src/logging/log-manager.js +426 -0
  43. package/src/progress-throttle.js +101 -0
  44. package/src/system-monitor.js +64 -0
  45. package/src/utils/format.js +16 -0
  46. package/src/utils/log-file-helper.js +265 -0
  47. package/src/utils/progress-parser.js +250 -0
  48. package/src/worktree-manager.js +255 -0
@@ -0,0 +1,264 @@
1
+ #!/bin/bash
2
+ # Ralph Agent Monitoring Script
3
+ # Ensures only one agent runs and provides visibility into its activity
4
+
5
+ AGENT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
6
+ AGENT_SCRIPT="$AGENT_DIR/bin/ralphblaster.js"
7
+ LOG_DIR="$HOME/.ralphblaster-logs"
8
+ CURRENT_LOG="$LOG_DIR/agent-$(date +%Y%m%d).log"
9
+ PID_FILE="$LOG_DIR/agent.pid"
10
+ STATUS_FILE="$LOG_DIR/agent-status.json"
11
+
12
+ # Create log directory
13
+ mkdir -p "$LOG_DIR"
14
+
15
+ # Function to check if agent is running
16
+ check_agent() {
17
+ if [ -f "$PID_FILE" ]; then
18
+ local pid=$(cat "$PID_FILE")
19
+ if ps -p "$pid" > /dev/null 2>&1; then
20
+ # Check if it's actually our agent process
21
+ if ps -p "$pid" -o command= | grep -q "ralphblaster"; then
22
+ return 0 # Running
23
+ fi
24
+ fi
25
+ # Stale PID file
26
+ rm -f "$PID_FILE"
27
+ fi
28
+ return 1 # Not running
29
+ }
30
+
31
+ # Function to kill all agent processes
32
+ kill_all_agents() {
33
+ echo "Searching for all Ralph agent processes..."
34
+ local pids=$(pgrep -f "ralphblaster.js")
35
+
36
+ if [ -z "$pids" ]; then
37
+ echo "No agent processes found"
38
+ return
39
+ fi
40
+
41
+ echo "Found agent processes: $pids"
42
+ for pid in $pids; do
43
+ echo "Killing process $pid..."
44
+ kill -TERM "$pid" 2>/dev/null
45
+ sleep 1
46
+ # Force kill if still running
47
+ if ps -p "$pid" > /dev/null 2>&1; then
48
+ echo "Force killing $pid..."
49
+ kill -KILL "$pid" 2>/dev/null
50
+ fi
51
+ done
52
+
53
+ rm -f "$PID_FILE"
54
+ echo "All agents stopped"
55
+ }
56
+
57
+ # Function to start agent
58
+ start_agent() {
59
+ if check_agent; then
60
+ echo "❌ Agent already running (PID: $(cat "$PID_FILE"))"
61
+ echo "Use 'monitor-agent.sh restart' to restart it"
62
+ return 1
63
+ fi
64
+
65
+ echo "Starting Ralph agent..."
66
+ echo "Logs: $CURRENT_LOG"
67
+
68
+ # Start agent with output to log file
69
+ cd "$AGENT_DIR"
70
+ RALPH_LOG_LEVEL="${RALPH_LOG_LEVEL:-info}" node "$AGENT_SCRIPT" >> "$CURRENT_LOG" 2>&1 &
71
+ local pid=$!
72
+
73
+ echo $pid > "$PID_FILE"
74
+
75
+ # Wait a moment to ensure it started
76
+ sleep 2
77
+
78
+ if check_agent; then
79
+ echo "✅ Agent started successfully (PID: $pid)"
80
+ echo ""
81
+ echo "Monitor logs with:"
82
+ echo " tail -f $CURRENT_LOG"
83
+ echo ""
84
+ echo "Check status with:"
85
+ echo " $0 status"
86
+ return 0
87
+ else
88
+ echo "❌ Agent failed to start"
89
+ echo "Check logs: $CURRENT_LOG"
90
+ return 1
91
+ fi
92
+ }
93
+
94
+ # Function to stop agent
95
+ stop_agent() {
96
+ if ! check_agent; then
97
+ echo "Agent not running"
98
+ # Clean up any zombie processes just in case
99
+ kill_all_agents
100
+ return 0
101
+ fi
102
+
103
+ local pid=$(cat "$PID_FILE")
104
+ echo "Stopping agent (PID: $pid)..."
105
+ kill -TERM "$pid" 2>/dev/null
106
+
107
+ # Wait for graceful shutdown
108
+ local timeout=10
109
+ while [ $timeout -gt 0 ]; do
110
+ if ! ps -p "$pid" > /dev/null 2>&1; then
111
+ rm -f "$PID_FILE"
112
+ echo "✅ Agent stopped"
113
+ return 0
114
+ fi
115
+ sleep 1
116
+ timeout=$((timeout - 1))
117
+ done
118
+
119
+ # Force kill if still running
120
+ echo "Force killing agent..."
121
+ kill -KILL "$pid" 2>/dev/null
122
+ rm -f "$PID_FILE"
123
+ echo "✅ Agent stopped (forced)"
124
+ }
125
+
126
+ # Function to show status
127
+ show_status() {
128
+ echo "=== Ralph Agent Status ==="
129
+ echo ""
130
+
131
+ # Check main agent
132
+ if check_agent; then
133
+ local pid=$(cat "$PID_FILE")
134
+ echo "✅ Main agent: RUNNING (PID: $pid)"
135
+
136
+ # Get process info
137
+ echo ""
138
+ echo "Process details:"
139
+ ps -p "$pid" -o pid,state,start,time,command | tail -n +2
140
+
141
+ # Get API token info
142
+ if [ -f "$HOME/.ralphblasterrc" ]; then
143
+ echo ""
144
+ echo "API Token: configured in ~/.ralphblasterrc"
145
+ fi
146
+
147
+ # Show recent activity from logs
148
+ echo ""
149
+ echo "Recent activity (last 5 lines):"
150
+ if [ -f "$CURRENT_LOG" ]; then
151
+ tail -5 "$CURRENT_LOG" | sed 's/^/ /'
152
+ else
153
+ echo " (no log file found)"
154
+ fi
155
+ else
156
+ echo "❌ Main agent: NOT RUNNING"
157
+ fi
158
+
159
+ echo ""
160
+ echo "=== All Ralph Agent Processes ==="
161
+ local all_pids=$(pgrep -f "ralphblaster.js")
162
+
163
+ if [ -z "$all_pids" ]; then
164
+ echo "No agent processes found"
165
+ else
166
+ echo "Found processes:"
167
+ for pid in $all_pids; do
168
+ echo ""
169
+ ps -p "$pid" -o pid,state,start,time,command | tail -n +2 | sed 's/^/ /'
170
+ done
171
+
172
+ # Warning if multiple agents
173
+ local count=$(echo "$all_pids" | wc -w)
174
+ if [ "$count" -gt 1 ]; then
175
+ echo ""
176
+ echo "⚠️ WARNING: Multiple agent processes detected!"
177
+ echo "This may cause jobs to be processed by different agents."
178
+ echo "Run '$0 restart' to ensure only one agent is running."
179
+ fi
180
+ fi
181
+
182
+ echo ""
183
+ echo "Logs directory: $LOG_DIR"
184
+ echo "Current log: $CURRENT_LOG"
185
+ }
186
+
187
+ # Function to tail logs
188
+ tail_logs() {
189
+ if [ ! -f "$CURRENT_LOG" ]; then
190
+ echo "No log file found at: $CURRENT_LOG"
191
+ return 1
192
+ fi
193
+
194
+ echo "Tailing agent logs (Ctrl+C to stop)..."
195
+ echo "File: $CURRENT_LOG"
196
+ echo ""
197
+ tail -f "$CURRENT_LOG"
198
+ }
199
+
200
+ # Function to show recent logs
201
+ show_logs() {
202
+ local lines="${1:-50}"
203
+
204
+ if [ ! -f "$CURRENT_LOG" ]; then
205
+ echo "No log file found at: $CURRENT_LOG"
206
+ return 1
207
+ fi
208
+
209
+ echo "Last $lines lines from agent log:"
210
+ echo "File: $CURRENT_LOG"
211
+ echo ""
212
+ tail -n "$lines" "$CURRENT_LOG"
213
+ }
214
+
215
+ # Main command handling
216
+ case "${1:-status}" in
217
+ start)
218
+ start_agent
219
+ ;;
220
+ stop)
221
+ stop_agent
222
+ ;;
223
+ restart)
224
+ echo "Restarting agent..."
225
+ kill_all_agents # Kill ALL agents, not just the tracked one
226
+ sleep 2
227
+ start_agent
228
+ ;;
229
+ status)
230
+ show_status
231
+ ;;
232
+ logs)
233
+ tail_logs
234
+ ;;
235
+ show-logs)
236
+ show_logs "${2:-50}"
237
+ ;;
238
+ kill-all)
239
+ kill_all_agents
240
+ ;;
241
+ *)
242
+ echo "Ralph Agent Monitor"
243
+ echo ""
244
+ echo "Usage: $0 [command]"
245
+ echo ""
246
+ echo "Commands:"
247
+ echo " start Start the agent (fails if already running)"
248
+ echo " stop Stop the agent gracefully"
249
+ echo " restart Kill all agents and start fresh"
250
+ echo " status Show agent status and recent activity"
251
+ echo " logs Tail agent logs in real-time"
252
+ echo " show-logs Show recent logs (default: 50 lines)"
253
+ echo " kill-all Kill all agent processes (use when stuck)"
254
+ echo ""
255
+ echo "Examples:"
256
+ echo " $0 start # Start the agent"
257
+ echo " $0 status # Check if agent is running"
258
+ echo " $0 logs # Watch live logs"
259
+ echo " $0 show-logs 100 # Show last 100 log lines"
260
+ echo " $0 restart # Fresh start (kills any zombies)"
261
+ echo ""
262
+ exit 1
263
+ ;;
264
+ esac
@@ -0,0 +1,247 @@
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 --agents flag (multi-agent mode)
7
+ const agentsIndex = args.findIndex(arg => arg.startsWith('--agents='));
8
+ let agentCount = null;
9
+ if (agentsIndex !== -1) {
10
+ agentCount = parseInt(args[agentsIndex].split('=')[1], 10);
11
+ // Get max agents from environment variable (default: 10)
12
+ const maxAgents = parseInt(process.env.RALPHBLASTER_MAX_AGENTS_PER_USER || process.env.RALPH_MAX_AGENTS_PER_USER || '10', 10);
13
+ if (isNaN(agentCount) || agentCount < 1 || agentCount > maxAgents) {
14
+ console.error(`Error: --agents flag requires a number between 1 and ${maxAgents}`);
15
+ process.exit(1);
16
+ }
17
+ }
18
+
19
+ // Check for --token flag
20
+ const tokenIndex = args.findIndex(arg => arg.startsWith('--token='));
21
+ if (tokenIndex !== -1) {
22
+ const token = args[tokenIndex].split('=')[1];
23
+ if (!token || token.trim() === '') {
24
+ console.error('Error: --token flag requires a value');
25
+ process.exit(1);
26
+ }
27
+ // Set both old and new variable names for backward compatibility
28
+ process.env.RALPHBLASTER_API_TOKEN = token;
29
+ process.env.RALPH_API_TOKEN = token;
30
+ }
31
+
32
+ // Check for --api-url flag
33
+ const apiUrlIndex = args.findIndex(arg => arg.startsWith('--api-url='));
34
+ if (apiUrlIndex !== -1) {
35
+ const apiUrl = args[apiUrlIndex].split('=')[1];
36
+ if (!apiUrl || apiUrl.trim() === '') {
37
+ console.error('Error: --api-url flag requires a value');
38
+ process.exit(1);
39
+ }
40
+ // Set both old and new variable names for backward compatibility
41
+ process.env.RALPHBLASTER_API_URL = apiUrl;
42
+ process.env.RALPH_API_URL = apiUrl;
43
+ }
44
+
45
+ // Show help
46
+ if (args.includes('--help') || args.includes('-h')) {
47
+ console.log(`
48
+ RalphBlaster Agent - Autonomous coding agent for RalphBlaster
49
+
50
+ Usage:
51
+ ralphblaster [options]
52
+ ralphblaster init [options]
53
+ ralphblaster add-project
54
+
55
+ Commands:
56
+ (default) Start the agent in polling mode
57
+ init Save credentials to ~/.ralphblasterrc
58
+ add-project Register current directory as a RalphBlaster project
59
+
60
+ Options:
61
+ --agents=<count> Run multiple agents concurrently (1-10, default: 1)
62
+ --token=<token> API token for authentication
63
+ --api-url=<url> API base URL (default: https://hq.ralphblaster.com)
64
+ --help, -h Show this help message
65
+
66
+ Getting Started:
67
+ 1. Save your credentials:
68
+ ralphblaster init --token=fm6ibAG6vamdjtbG5snuD3F4
69
+
70
+ 2. Register your project (run in project directory):
71
+ ralphblaster add-project
72
+
73
+ 3. Start the agent:
74
+ ralphblaster
75
+
76
+ Configuration:
77
+ Token is loaded from (in order of priority):
78
+ 1. --token flag
79
+ 2. RALPHBLASTER_API_TOKEN (or RALPH_API_TOKEN) environment variable
80
+ 3. ~/.ralphblasterrc config file
81
+
82
+ Environment Variables:
83
+ RALPHBLASTER_API_TOKEN API token (RALPH_API_TOKEN also supported)
84
+ RALPHBLASTER_API_URL API base URL (RALPH_API_URL also supported)
85
+ RALPHBLASTER_LOG_LEVEL Log level: error, warn, info, debug (default: info)
86
+ RALPHBLASTER_MAX_AGENTS_PER_USER Max concurrent agents (default: 10)
87
+ RALPHBLASTER_ALLOWED_PATHS Colon-separated list of allowed base paths
88
+ (optional security whitelist)
89
+ RALPHBLASTER_AGENT_ID Agent identifier for multi-agent setups
90
+
91
+ Note: RALPH_* variables are supported for backward compatibility but deprecated.
92
+
93
+ Examples:
94
+ # First time setup - save credentials
95
+ ralphblaster init --token=your_token_here --api-url=https://hq.ralphblaster.com
96
+
97
+ # Register project with API
98
+ cd /path/to/your/project
99
+ ralphblaster add-project
100
+
101
+ # Start single agent (uses token from ~/.ralphblasterrc)
102
+ ralphblaster
103
+
104
+ # Run 3 agents concurrently for parallel job processing
105
+ ralphblaster --agents=3
106
+
107
+ # Run with environment variable (if not using ~/.ralphblasterrc)
108
+ RALPHBLASTER_API_TOKEN=your_token_here ralphblaster
109
+
110
+ # Run with custom API URL
111
+ ralphblaster --api-url=http://localhost:3000
112
+
113
+ # Use with npm
114
+ npm start -- --agents=3
115
+ `);
116
+ process.exit(0);
117
+ }
118
+
119
+ // Check for version
120
+ if (args.includes('--version') || args.includes('-v')) {
121
+ const packageJson = require('../package.json');
122
+ console.log(`ralphblaster v${packageJson.version}`);
123
+ process.exit(0);
124
+ }
125
+
126
+ // Check for init command
127
+ if (args.includes('init')) {
128
+ const InitCommand = require('../src/commands/init');
129
+ const initCmd = new InitCommand();
130
+ initCmd.run().catch(error => {
131
+ // Error handling is done in InitCommand.handleError
132
+ // Just exit with error code
133
+ });
134
+ return; // Don't start agent polling loop
135
+ }
136
+
137
+ // Check for add-project command (alias for init)
138
+ if (args.includes('add-project')) {
139
+ const AddProjectCommand = require('../src/commands/add-project');
140
+ const addProjectCmd = new AddProjectCommand();
141
+ addProjectCmd.run().catch(error => {
142
+ // Error handling is done in AddProjectCommand.handleError
143
+ // Just exit with error code
144
+ });
145
+ return; // Don't start agent polling loop
146
+ }
147
+
148
+ // Multi-agent mode: Launch multiple agent processes
149
+ if (agentCount && agentCount > 1) {
150
+ const { spawn } = require('child_process');
151
+ const path = require('path');
152
+
153
+ console.log('');
154
+ console.log('╔════════════════════════════════════════════════════════════╗');
155
+ console.log(`║ RalphBlaster Multi-Agent Manager - Starting ${agentCount} agents ║`);
156
+ console.log('╚════════════════════════════════════════════════════════════╝');
157
+ console.log('');
158
+
159
+ const agents = [];
160
+ const agentProcesses = [];
161
+
162
+ // Cleanup function for graceful shutdown
163
+ const cleanup = () => {
164
+ console.log('\n\nShutting down all agents...');
165
+ agentProcesses.forEach((proc, index) => {
166
+ if (proc && !proc.killed) {
167
+ console.log(` Stopping agent-${index + 1} (PID: ${proc.pid})`);
168
+ proc.kill('SIGTERM');
169
+ }
170
+ });
171
+ setTimeout(() => {
172
+ console.log('All agents stopped');
173
+ process.exit(0);
174
+ }, 500);
175
+ };
176
+
177
+ // Setup signal handlers
178
+ process.on('SIGINT', cleanup);
179
+ process.on('SIGTERM', cleanup);
180
+
181
+ // Launch each agent
182
+ for (let i = 1; i <= agentCount; i++) {
183
+ const agentId = `agent-${i}`;
184
+
185
+ // Spawn agent process with unique ID
186
+ const agentProcess = spawn('node', [path.join(__dirname, 'ralphblaster.js')], {
187
+ env: {
188
+ ...process.env,
189
+ RALPHBLASTER_AGENT_ID: agentId,
190
+ RALPH_AGENT_ID: agentId // Set both for backward compatibility
191
+ },
192
+ stdio: 'inherit' // Share stdio with parent for unified logging
193
+ });
194
+
195
+ agentProcesses.push(agentProcess);
196
+
197
+ // Handle agent exit
198
+ agentProcess.on('exit', (code, signal) => {
199
+ if (code !== 0 && code !== null) {
200
+ console.error(`\nAgent ${agentId} exited with code ${code}`);
201
+ }
202
+
203
+ // If any agent dies unexpectedly, shut down all
204
+ if (signal || (code && code !== 0)) {
205
+ console.error(`\nAgent ${agentId} failed, shutting down all agents...`);
206
+ cleanup();
207
+ }
208
+ });
209
+
210
+ console.log(`✓ Started ${agentId} (PID: ${agentProcess.pid})`);
211
+ }
212
+
213
+ console.log('');
214
+ console.log(`All ${agentCount} agents launched. Press Ctrl+C to stop all agents`);
215
+ console.log('');
216
+
217
+ // Keep process alive
218
+ return;
219
+ }
220
+
221
+ // Single agent mode (default)
222
+ // Load modules AFTER environment variables are set
223
+ // Wrap in try-catch to handle config errors gracefully
224
+ let RalphAgent, logger;
225
+ try {
226
+ RalphAgent = require('../src/index');
227
+ logger = require('../src/logger');
228
+ } catch (error) {
229
+ // Handle config errors (e.g., missing API token)
230
+ console.error('Error: ' + error.message);
231
+ process.exit(1);
232
+ }
233
+
234
+ // Start the agent
235
+ const agent = new RalphAgent();
236
+
237
+ logger.info('');
238
+ logger.info('╔═══════════════════════════════════════════╗');
239
+ logger.info('║ RalphBlaster Agent Starting... ║');
240
+ logger.info('╚═══════════════════════════════════════════╝');
241
+ logger.info('');
242
+
243
+ agent.start().catch(error => {
244
+ logger.error('Fatal error starting agent: ' + (error?.message || error));
245
+ console.error(error); // Also log full error with stack trace
246
+ process.exit(1);
247
+ });
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "ralphblaster-agent",
3
+ "version": "0.1.1",
4
+ "description": "RalphBlaster agent that polls for and executes coding jobs via Claude CLI",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "ralphblaster": "bin/ralphblaster.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "src/",
12
+ "postinstall-colored.js",
13
+ "LICENSE",
14
+ "README.md"
15
+ ],
16
+ "scripts": {
17
+ "start": "node bin/ralphblaster.js",
18
+ "start:multi": "node bin/ralphblaster.js --agents=3",
19
+ "start:multi:5": "node bin/ralphblaster.js --agents=5",
20
+ "test": "jest",
21
+ "test:watch": "jest --watch",
22
+ "test:coverage": "jest --coverage",
23
+ "postinstall": "node postinstall-colored.js"
24
+ },
25
+ "keywords": [
26
+ "ralph",
27
+ "agent",
28
+ "claude",
29
+ "automation"
30
+ ],
31
+ "author": "Wildfront LLC",
32
+ "license": "MIT",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/Wildfront/ralphblaster-agent.git"
36
+ },
37
+ "homepage": "https://github.com/Wildfront/ralphblaster-agent#readme",
38
+ "bugs": {
39
+ "url": "https://github.com/Wildfront/ralphblaster-agent/issues"
40
+ },
41
+ "dependencies": {
42
+ "axios": "^1.6.0",
43
+ "dotenv": "^16.3.1",
44
+ "secure-json-parse": "^4.1.0"
45
+ },
46
+ "devDependencies": {
47
+ "@types/jest": "^29.5.14",
48
+ "jest": "^29.7.0"
49
+ },
50
+ "jest": {
51
+ "testEnvironment": "node",
52
+ "coverageDirectory": "coverage",
53
+ "collectCoverageFrom": [
54
+ "src/**/*.js",
55
+ "!src/logger.js"
56
+ ],
57
+ "testMatch": [
58
+ "**/test/**/*.test.js"
59
+ ]
60
+ },
61
+ "engines": {
62
+ "node": ">=18.0.0"
63
+ }
64
+ }
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+
7
+ // ANSI color codes
8
+ const colors = {
9
+ reset: '\x1b[0m',
10
+ bright: '\x1b[1m',
11
+ dim: '\x1b[2m',
12
+ gray: '\x1b[90m',
13
+ cyan: '\x1b[36m',
14
+ green: '\x1b[32m',
15
+ yellow: '\x1b[33m',
16
+ orange: '\x1b[38;5;208m',
17
+ red: '\x1b[31m',
18
+ };
19
+
20
+ const ralph = `
21
+ ${colors.gray} /\\
22
+ / \\
23
+ / \\
24
+ | |
25
+ | ${colors.bright}${colors.yellow}${colors.reset}${colors.gray}${colors.bright}${colors.yellow}.${colors.reset}${colors.gray} |
26
+ | ${colors.yellow}(${colors.bright}${colors.yellow}o${colors.reset}${colors.yellow})${colors.reset}${colors.gray} | ${colors.bright}${colors.yellow}Ralph Agent${colors.reset}
27
+ | ${colors.yellow}(${colors.bright}${colors.yellow}o${colors.reset}${colors.yellow})${colors.reset}${colors.gray} | ${colors.dim}v1.3.4${colors.reset}
28
+ | ${colors.yellow}~${colors.reset}${colors.gray} |
29
+ | ${colors.red}\\___/${colors.reset}${colors.gray} |
30
+ | |
31
+ | |
32
+ | |
33
+ /| |\\
34
+ / | | \\
35
+ / | | \\
36
+ /__/| |\\__\\
37
+ ${colors.orange}/|${colors.reset}${colors.gray} ${colors.orange}|\\${colors.reset}
38
+ ${colors.orange}/ |${colors.reset}${colors.gray} ${colors.orange}| \\${colors.reset}
39
+ ${colors.bright}${colors.yellow}/ ${colors.reset}${colors.orange}|${colors.reset}${colors.gray} ${colors.orange}| ${colors.bright}${colors.yellow}\\${colors.reset}
40
+ ${colors.bright}${colors.yellow}' ${colors.reset}${colors.orange}|${colors.reset}${colors.gray} ${colors.orange}| ${colors.bright}${colors.yellow}'${colors.reset}
41
+ ${colors.orange}|${colors.reset}${colors.gray} ${colors.orange}|${colors.reset}
42
+ `;
43
+
44
+ // No plugin installation needed - skill is bundled with the agent
45
+
46
+ const message = `
47
+ ${ralph}
48
+
49
+ ${colors.bright}${colors.green}Installed successfully!${colors.reset}
50
+
51
+ ${colors.green}Getting Started:${colors.reset}
52
+
53
+ ${colors.dim}1.${colors.reset} Make sure Claude CLI is installed:
54
+ ${colors.yellow}claude --version${colors.reset}
55
+
56
+ ${colors.dim}2.${colors.reset} Get your API token from Ralph (requires 'ralph_agent' permission)
57
+
58
+ ${colors.dim}3.${colors.reset} Start the agent:
59
+ ${colors.yellow}ralphblaster --token=your_api_token_here${colors.reset}
60
+
61
+ ${colors.green}Documentation:${colors.reset}
62
+ ${colors.cyan}https://github.com/Wildfront/ralphblaster-agent#readme${colors.reset}
63
+
64
+ `;
65
+
66
+ console.log(message);