import { parseArgs, getString, getNumber } from "../utils/parseArgs.js";
/**
* start_ralph 智能编排工具
*
* 场景:Ralph Wiggum Loop 循环开发
* 编排:生成 .ralph/ 目录结构 + 安全模式脚本 + 执行指南
*/
interface RalphArgs {
goal?: string;
mode?: string;
completion_promise?: string;
test_command?: string;
cli_command?: string;
max_iterations?: number;
max_minutes?: number;
confirm_every?: number;
confirm_timeout?: number;
max_same_output?: number;
max_diff_lines?: number;
cooldown_seconds?: number;
}
// 默认值(保守安全)
const DEFAULTS = {
mode: "safe",
completion_promise: "tests passing + requirements met",
test_command: "npm test",
cli_command: "claude-code",
max_iterations: 8,
max_minutes: 25,
confirm_every: 1,
confirm_timeout: 20,
max_same_output: 2,
max_diff_lines: 300,
cooldown_seconds: 8,
};
/**
* 生成 PROMPT.md 模板
*/
function generatePromptTemplate(goal: string, completionPromise: string, testCommand: string): string {
return `# Ralph Wiggum Loop - Development Prompt
## 🎯 Goal
${goal}
## ✅ Completion Promise
**Exit Condition**: ${completionPromise}
You MUST satisfy BOTH conditions to exit:
1. \`COMPLETION_PROMISE_MET: true\`
2. \`EXIT_SIGNAL: true\`
## 📋 Iteration Rules
### 1. Small Steps
- Make ONE focused change per iteration
- Avoid large refactors in a single iteration
- Keep changes under ${DEFAULTS.max_diff_lines} lines when possible
### 2. Test First
- **CRITICAL**: First iteration MUST identify the correct test command for this project
- Check for: package.json scripts, pytest, cargo test, go test, mvn test, etc.
- Update this PROMPT.md with the correct command
- Run tests EVERY iteration: \`${testCommand}\`
- Do NOT proceed if tests fail (unless fixing test failures is the goal)
### 3. Update Progress
- Update \`@fix_plan.md\` after each iteration
- Mark completed tasks with ✅
- Add new discovered tasks
- Adjust priorities
- Update \`PROGRESS.md\` with:
- What was done
- Test results
- Next step
- Current status
### 4. State Block (REQUIRED)
At the end of EVERY response, output:
\`\`\`
COMPLETION_PROMISE_MET: [true|false]
EXIT_SIGNAL: [true|false]
SUMMARY: [one-line summary of this iteration]
NEXT_STEP: [what to do next, or "EXIT" if done]
\`\`\`
**Exit Logic**:
- Set \`COMPLETION_PROMISE_MET: true\` only when completion promise is satisfied
- Set \`EXIT_SIGNAL: true\` only when you're confident to exit
- Loop continues if EITHER is false
### 5. Safety Checks
- If stuck or repeating same action → set \`EXIT_SIGNAL: true\` and ask for help
- If single change exceeds ${DEFAULTS.max_diff_lines} lines → stop and break into smaller tasks
- If tests keep failing after 3 attempts → stop and ask for help
---
## 📂 Files
- \`@fix_plan.md\`: Task breakdown and priorities
- \`PROGRESS.md\`: Iteration log
- \`STOP\`: Create this file to emergency stop
---
*Generated by MCP Probe Kit - start_ralph*
`;
}
/**
* 生成 @fix_plan.md 模板
*/
function generateFixPlanTemplate(goal: string): string {
return `# Task Plan: ${goal}
## 🎯 Goal
${goal}
## 📋 Tasks
### ✅ Completed
- [ ] Identify correct test command
- [ ] Verify project structure
### 🚧 In Progress
- [ ] [Task will be added by agent]
### 📝 Todo
- [ ] [Tasks will be added by agent]
### 🔍 Discovered Issues
- [Issues will be added during iterations]
---
**Instructions for Agent**:
1. First iteration: identify test command and update PROMPT.md
2. Break down goal into small, testable tasks
3. Mark tasks as completed with ✅
4. Add new tasks as discovered
5. Keep this file updated every iteration
`;
}
/**
* 生成 PROGRESS.md 模板
*/
function generateProgressTemplate(): string {
return `# Ralph Loop Progress Log
## Iteration Summary
| Iter | Time | Changed Lines | Tests | Status | Summary |
|------|------|---------------|-------|--------|---------|
| 0 | - | - | - | START | Loop initialized |
---
## Detailed Log
### Iteration 0 - Initialization
- **Time**: [timestamp]
- **Action**: Loop started
- **Next**: Identify test command and begin first task
---
**Instructions for Agent**:
- Add entry for each iteration
- Include: iteration number, timestamp, what was done, test results, next step
- Keep summary table updated
`;
}
/**
* 生成安全模式脚本 (Bash)
*/
function generateSafeScript(params: Required<RalphArgs>): string {
return `#!/bin/bash
# Ralph Loop - Safe Mode
# Generated by MCP Probe Kit
set -euo pipefail
# ============================================
# SAFETY PARAMETERS (Override with env vars)
# ============================================
MAX_ITERS=\${MAX_ITERS:-${params.max_iterations}}
MAX_MINUTES=\${MAX_MINUTES:-${params.max_minutes}}
CONFIRM_EVERY=\${CONFIRM_EVERY:-${params.confirm_every}}
CONFIRM_TIMEOUT=\${CONFIRM_TIMEOUT:-${params.confirm_timeout}}
MAX_SAME_OUTPUT=\${MAX_SAME_OUTPUT:-${params.max_same_output}}
MAX_DIFF_LINES=\${MAX_DIFF_LINES:-${params.max_diff_lines}}
COOLDOWN_SECONDS=\${COOLDOWN_SECONDS:-${params.cooldown_seconds}}
REQUIRE_TTY=\${REQUIRE_TTY:-1}
CLI_COMMAND=\${CLI_COMMAND:-${params.cli_command}}
# ============================================
# SAFETY CHECKS
# ============================================
if [ "$REQUIRE_TTY" = "1" ] && [ ! -t 0 ]; then
echo "❌ ERROR: Not running in interactive terminal (TTY required for safety)"
echo " To override: REQUIRE_TTY=0 $0"
exit 1
fi
if [ ! -f "PROMPT.md" ]; then
echo "❌ ERROR: PROMPT.md not found. Run from .ralph/ directory"
exit 1
fi
# ============================================
# STARTUP WARNING
# ============================================
echo "🚀 Ralph Loop - Safe Mode"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "⚠️ Safety Limits:"
echo " • Max iterations: $MAX_ITERS"
echo " • Max time: $MAX_MINUTES minutes"
echo " • Confirm every: $CONFIRM_EVERY iteration(s)"
echo " • Confirm timeout: $CONFIRM_TIMEOUT seconds"
echo " • Max same output: $MAX_SAME_OUTPUT times"
echo " • Max diff lines: $MAX_DIFF_LINES lines"
echo ""
echo "💡 Emergency stop: touch STOP"
echo "💡 Pause: Ctrl+C"
echo ""
echo "Press Ctrl+C to cancel, or wait 5s to start..."
sleep 5
# ============================================
# INITIALIZATION
# ============================================
ITER=0
START_TIME=$(date +%s)
LAST_OUTPUT_HASH=""
SAME_OUTPUT_COUNT=0
LOG_FILE="ralph.log"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] Loop started" >> "$LOG_FILE"
# ============================================
# MAIN LOOP
# ============================================
while [ $ITER -lt $MAX_ITERS ]; do
ITER=$((ITER + 1))
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔄 Iteration $ITER / $MAX_ITERS"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Check: STOP file
if [ -f "STOP" ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [SAFE] STOP file detected" >> "$LOG_FILE"
echo "🛑 STOP file detected. Emergency exit."
exit 0
fi
# Check: Max time
CURRENT_TIME=$(date +%s)
ELAPSED_MINUTES=$(( (CURRENT_TIME - START_TIME) / 60 ))
if [ $ELAPSED_MINUTES -ge $MAX_MINUTES ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [SAFE] Max time reached: $ELAPSED_MINUTES min" >> "$LOG_FILE"
echo "⏰ Max time ($MAX_MINUTES min) reached. Stopping."
exit 0
fi
# Check: Confirmation required
if [ $((ITER % CONFIRM_EVERY)) -eq 0 ]; then
echo ""
echo "⏸️ Confirmation required (timeout: \${CONFIRM_TIMEOUT}s)"
echo -n " Continue? [y/N]: "
if read -t $CONFIRM_TIMEOUT -r REPLY; then
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [SAFE] User declined to continue" >> "$LOG_FILE"
echo "🛑 User stopped the loop."
exit 0
fi
else
echo ""
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [SAFE] Confirmation timeout" >> "$LOG_FILE"
echo "⏰ Confirmation timeout. Stopping for safety."
exit 0
fi
fi
# Execute Claude Code
echo "🤖 Running: $CLI_COMMAND @PROMPT.md"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] Iteration $ITER started" >> "$LOG_FILE"
OUTPUT_FILE="last_output_$ITER.txt"
if $CLI_COMMAND @PROMPT.md > "$OUTPUT_FILE" 2>&1; then
cat "$OUTPUT_FILE"
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] CLI command failed" >> "$LOG_FILE"
echo "❌ CLI command failed. Check $OUTPUT_FILE"
exit 1
fi
# Check: Output repetition
CURRENT_HASH=$(md5sum "$OUTPUT_FILE" 2>/dev/null | cut -d' ' -f1 || echo "")
if [ "$CURRENT_HASH" = "$LAST_OUTPUT_HASH" ]; then
SAME_OUTPUT_COUNT=$((SAME_OUTPUT_COUNT + 1))
if [ $SAME_OUTPUT_COUNT -ge $MAX_SAME_OUTPUT ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [WARN] Output repeated $SAME_OUTPUT_COUNT times" >> "$LOG_FILE"
echo "⚠️ Output repeated $SAME_OUTPUT_COUNT times. Likely stuck. Stopping."
exit 0
fi
else
SAME_OUTPUT_COUNT=0
fi
LAST_OUTPUT_HASH="$CURRENT_HASH"
# Check: Git diff size (if in git repo)
if git rev-parse --git-dir > /dev/null 2>&1; then
CHANGED_LINES=$(git diff --stat | tail -1 | grep -oE '[0-9]+ insertion|[0-9]+ deletion' | grep -oE '[0-9]+' | awk '{s+=$1} END {print s}' || echo "0")
if [ "$CHANGED_LINES" -gt "$MAX_DIFF_LINES" ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [WARN] Changed lines ($CHANGED_LINES) exceeds limit ($MAX_DIFF_LINES)" >> "$LOG_FILE"
echo "⚠️ Changed $CHANGED_LINES lines (limit: $MAX_DIFF_LINES). Please review manually."
echo " Run: git diff --stat"
exit 0
fi
fi
# Check: Exit signals in output
if grep -q "COMPLETION_PROMISE_MET: true" "$OUTPUT_FILE" && grep -q "EXIT_SIGNAL: true" "$OUTPUT_FILE"; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] Both exit conditions met" >> "$LOG_FILE"
echo "✅ Completion promise met and exit signal received. Success!"
exit 0
fi
# Cooldown
echo "😴 Cooldown: \${COOLDOWN_SECONDS}s..."
sleep $COOLDOWN_SECONDS
done
# Max iterations reached
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [SAFE] Max iterations reached" >> "$LOG_FILE"
echo "⏰ Max iterations ($MAX_ITERS) reached. Stopping."
exit 0
`;
}
/**
* 生成普通模式脚本 (Bash)
*/
function generateNormalScript(params: Required<RalphArgs>): string {
return `#!/bin/bash
# Ralph Loop - Normal Mode (Use with caution!)
# Generated by MCP Probe Kit
set -euo pipefail
# ============================================
# PARAMETERS
# ============================================
MAX_ITERS=\${MAX_ITERS:-${params.max_iterations}}
CLI_COMMAND=\${CLI_COMMAND:-${params.cli_command}}
echo "🚀 Ralph Loop - Normal Mode"
echo "⚠️ WARNING: No confirmation required. Use Ctrl+C to stop."
echo " Max iterations: $MAX_ITERS"
echo ""
sleep 3
ITER=0
LOG_FILE="ralph.log"
while [ $ITER -lt $MAX_ITERS ]; do
ITER=$((ITER + 1))
echo "🔄 Iteration $ITER / $MAX_ITERS"
if [ -f "STOP" ]; then
echo "🛑 STOP file detected."
exit 0
fi
OUTPUT_FILE="last_output_$ITER.txt"
$CLI_COMMAND @PROMPT.md | tee "$OUTPUT_FILE"
if grep -q "COMPLETION_PROMISE_MET: true" "$OUTPUT_FILE" && grep -q "EXIT_SIGNAL: true" "$OUTPUT_FILE"; then
echo "✅ Success!"
exit 0
fi
sleep 5
done
echo "⏰ Max iterations reached."
exit 0
`;
}
/**
* 生成 Windows 安全模式脚本 (PowerShell)
*/
function generateSafeScriptWindows(params: Required<RalphArgs>): string {
return `# Ralph Loop - Safe Mode (Windows)
# Generated by MCP Probe Kit
$ErrorActionPreference = "Stop"
# ============================================
# SAFETY PARAMETERS
# ============================================
$MAX_ITERS = if ($env:MAX_ITERS) { [int]$env:MAX_ITERS } else { ${params.max_iterations} }
$MAX_MINUTES = if ($env:MAX_MINUTES) { [int]$env:MAX_MINUTES } else { ${params.max_minutes} }
$CONFIRM_EVERY = if ($env:CONFIRM_EVERY) { [int]$env:CONFIRM_EVERY } else { ${params.confirm_every} }
$CONFIRM_TIMEOUT = if ($env:CONFIRM_TIMEOUT) { [int]$env:CONFIRM_TIMEOUT } else { ${params.confirm_timeout} }
$MAX_SAME_OUTPUT = if ($env:MAX_SAME_OUTPUT) { [int]$env:MAX_SAME_OUTPUT } else { ${params.max_same_output} }
$MAX_DIFF_LINES = if ($env:MAX_DIFF_LINES) { [int]$env:MAX_DIFF_LINES } else { ${params.max_diff_lines} }
$COOLDOWN_SECONDS = if ($env:COOLDOWN_SECONDS) { [int]$env:COOLDOWN_SECONDS } else { ${params.cooldown_seconds} }
$CLI_COMMAND = if ($env:CLI_COMMAND) { $env:CLI_COMMAND } else { "${params.cli_command}" }
if (-not (Test-Path "PROMPT.md")) {
Write-Host "❌ ERROR: PROMPT.md not found" -ForegroundColor Red
exit 1
}
Write-Host "🚀 Ralph Loop - Safe Mode" -ForegroundColor Cyan
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
Write-Host "⚠️ Safety Limits:"
Write-Host " • Max iterations: $MAX_ITERS"
Write-Host " • Max time: $MAX_MINUTES minutes"
Write-Host " • Confirm every: $CONFIRM_EVERY iteration(s)"
Write-Host ""
Write-Host "💡 Emergency stop: New-Item -ItemType File -Name STOP"
Write-Host ""
Write-Host "Press Ctrl+C to cancel, or wait 5s to start..."
Start-Sleep -Seconds 5
$ITER = 0
$START_TIME = Get-Date
$LAST_OUTPUT_HASH = ""
$SAME_OUTPUT_COUNT = 0
$LOG_FILE = "ralph.log"
Add-Content -Path $LOG_FILE -Value "[$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))] [INFO] Loop started"
while ($ITER -lt $MAX_ITERS) {
$ITER++
Write-Host ""
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
Write-Host "🔄 Iteration $ITER / $MAX_ITERS" -ForegroundColor Yellow
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if (Test-Path "STOP") {
Add-Content -Path $LOG_FILE -Value "[$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))] [SAFE] STOP file detected"
Write-Host "🛑 STOP file detected. Emergency exit." -ForegroundColor Red
exit 0
}
$ELAPSED_MINUTES = ((Get-Date) - $START_TIME).TotalMinutes
if ($ELAPSED_MINUTES -ge $MAX_MINUTES) {
Add-Content -Path $LOG_FILE -Value "[$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))] [SAFE] Max time reached"
Write-Host "⏰ Max time reached. Stopping." -ForegroundColor Yellow
exit 0
}
if ($ITER % $CONFIRM_EVERY -eq 0) {
Write-Host ""
Write-Host "⏸️ Confirmation required" -ForegroundColor Yellow
$response = Read-Host " Continue? [y/N]"
if ($response -notmatch '^[Yy]$') {
Add-Content -Path $LOG_FILE -Value "[$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))] [SAFE] User declined"
Write-Host "🛑 User stopped the loop." -ForegroundColor Red
exit 0
}
}
Write-Host "🤖 Running: $CLI_COMMAND @PROMPT.md"
$OUTPUT_FILE = "last_output_$ITER.txt"
& $CLI_COMMAND "@PROMPT.md" | Tee-Object -FilePath $OUTPUT_FILE
$CURRENT_HASH = (Get-FileHash -Path $OUTPUT_FILE -Algorithm MD5).Hash
if ($CURRENT_HASH -eq $LAST_OUTPUT_HASH) {
$SAME_OUTPUT_COUNT++
if ($SAME_OUTPUT_COUNT -ge $MAX_SAME_OUTPUT) {
Write-Host "⚠️ Output repeated. Likely stuck. Stopping." -ForegroundColor Yellow
exit 0
}
} else {
$SAME_OUTPUT_COUNT = 0
}
$LAST_OUTPUT_HASH = $CURRENT_HASH
$content = Get-Content $OUTPUT_FILE -Raw
if ($content -match "COMPLETION_PROMISE_MET: true" -and $content -match "EXIT_SIGNAL: true") {
Write-Host "✅ Success!" -ForegroundColor Green
exit 0
}
Write-Host "😴 Cooldown: \${COOLDOWN_SECONDS}s..."
Start-Sleep -Seconds $COOLDOWN_SECONDS
}
Write-Host "⏰ Max iterations reached." -ForegroundColor Yellow
exit 0
`;
}
/**
* 生成执行指南
*/
function generateGuide(params: Required<RalphArgs>, isWindows: boolean): string {
const scriptName = isWindows ? "ralph_loop_safe.ps1" : "ralph_loop_safe.sh";
const scriptCmd = isWindows ? `powershell -ExecutionPolicy Bypass -File ${scriptName}` : `./${scriptName}`;
const chmodCmd = isWindows ? "" : `chmod +x ${scriptName}\n`;
return `# 🚀 Ralph Loop Setup Complete!
## 📂 Generated Files
\`.ralph/\` directory structure:
- \`PROMPT.md\` - Loop prompt with goal and rules
- \`@fix_plan.md\` - Task breakdown (updated by agent)
- \`PROGRESS.md\` - Iteration log (updated by agent)
- \`${scriptName}\` - Safe mode script (default)
- \`ralph_loop.sh\` - Normal mode script (optional, use with caution)
---
## 🎯 Goal
${params.goal}
**Completion Promise**: ${params.completion_promise}
---
## 🛡️ Safety Configuration (Mode: ${params.mode})
| Parameter | Value | Description |
|-----------|-------|-------------|
| Max Iterations | ${params.max_iterations} | Hard limit on loop count |
| Max Minutes | ${params.max_minutes} | Hard limit on runtime |
| Confirm Every | ${params.confirm_every} | Require confirmation every N iterations |
| Confirm Timeout | ${params.confirm_timeout}s | Auto-stop if no response |
| Max Same Output | ${params.max_same_output} | Stop if output repeats N times |
| Max Diff Lines | ${params.max_diff_lines} | Stop if changes exceed N lines |
| Cooldown | ${params.cooldown_seconds}s | Pause between iterations |
---
## 🚀 How to Start
### 1. Create .ralph directory
\`\`\`bash
mkdir -p .ralph
cd .ralph
\`\`\`
### 2. Copy files
Copy the generated content below into respective files:
- \`PROMPT.md\`
- \`@fix_plan.md\`
- \`PROGRESS.md\`
- \`${scriptName}\`
### 3. Make script executable${isWindows ? "" : " (Linux/Mac)"}
\`\`\`bash
${chmodCmd}\`\`\`
### 4. Run the loop
\`\`\`bash
${scriptCmd}
\`\`\`
---
## 🛑 How to Stop
### Emergency Stop
\`\`\`bash
touch .ralph/STOP
\`\`\`
The loop will exit immediately on next check.
### Manual Stop
Press \`Ctrl+C\` in the terminal.
### Timeout Stop
Don't respond to confirmation prompt (waits ${params.confirm_timeout}s then stops).
---
## ⚙️ How to Adjust Parameters
Override via environment variables:
\`\`\`bash
# Example: Increase max iterations to 15
${isWindows ? "$env:MAX_ITERS=15" : "MAX_ITERS=15"} ${scriptCmd}
# Example: Disable confirmation (not recommended!)
${isWindows ? "$env:CONFIRM_EVERY=999" : "CONFIRM_EVERY=999"} ${scriptCmd}
# Example: Use different CLI command
${isWindows ? "$env:CLI_COMMAND='claude'" : "CLI_COMMAND='claude'"} ${scriptCmd}
\`\`\`
Available overrides:
- \`MAX_ITERS\`
- \`MAX_MINUTES\`
- \`CONFIRM_EVERY\`
- \`CONFIRM_TIMEOUT\`
- \`MAX_SAME_OUTPUT\`
- \`MAX_DIFF_LINES\`
- \`COOLDOWN_SECONDS\`
- \`CLI_COMMAND\`
---
## 📊 How to Monitor
### View logs
\`\`\`bash
tail -f .ralph/ralph.log
\`\`\`
### Check progress
\`\`\`bash
cat .ralph/PROGRESS.md
\`\`\`
### Check tasks
\`\`\`bash
cat .ralph/@fix_plan.md
\`\`\`
### View last output
\`\`\`bash
cat .ralph/last_output_*.txt
\`\`\`
---
## 💡 Tips
1. **First iteration is critical**: The agent will identify the correct test command for your project
2. **Watch for repetition**: If output repeats ${params.max_same_output} times, loop auto-stops
3. **Review large changes**: If changes exceed ${params.max_diff_lines} lines, loop stops for manual review
4. **Use git**: Loop works best in git repos (tracks changes, can auto-backup)
5. **Start small**: Default limits are conservative - adjust after successful runs
---
## ⚠️ Warnings
- **Cost**: Each iteration calls the LLM API. Monitor usage!
- **Normal mode**: Use only when you're confident. No confirmations = potential runaway.
- **Test command**: Wrong test command = wasted iterations. Verify in first run.
- **Background execution**: Not recommended. Always run in foreground with TTY.
---
## 🔗 Integration with Other Tools
### Recommended workflow:
1. **Generate context** (optional but recommended):
\`\`\`bash
${params.cli_command} "使用 init_project_context 生成项目文档"
\`\`\`
2. **Generate feature spec** (if building new feature):
\`\`\`bash
${params.cli_command} "使用 start_feature 生成功能规格,goal='${params.goal}'"
\`\`\`
3. **Start Ralph Loop**:
\`\`\`bash
cd .ralph
${scriptCmd}
\`\`\`
---
*Generated by MCP Probe Kit - start_ralph v1.0*
`;
}
/**
* start_ralph 主函数
*/
export async function startRalph(args: any) {
try {
const parsedArgs = parseArgs<RalphArgs>(args, {
defaultValues: DEFAULTS,
primaryField: "goal",
fieldAliases: {
goal: ["目标", "任务", "task"],
mode: ["模式"],
completion_promise: ["完成条件", "退出条件"],
test_command: ["测试命令"],
cli_command: ["命令", "cli"],
max_iterations: ["最大迭代", "max_iters"],
max_minutes: ["最大时间", "max_time"],
confirm_every: ["确认频率"],
confirm_timeout: ["确认超时"],
max_same_output: ["最大重复"],
max_diff_lines: ["最大变更行数"],
cooldown_seconds: ["冷却时间"],
},
});
const goal = getString(parsedArgs.goal) || "Complete the development task";
const mode = getString(parsedArgs.mode) || DEFAULTS.mode;
const completionPromise = getString(parsedArgs.completion_promise) || DEFAULTS.completion_promise;
const testCommand = getString(parsedArgs.test_command) || DEFAULTS.test_command;
const cliCommand = getString(parsedArgs.cli_command) || DEFAULTS.cli_command;
const params: Required<RalphArgs> = {
goal,
mode,
completion_promise: completionPromise,
test_command: testCommand,
cli_command: cliCommand,
max_iterations: getNumber(parsedArgs.max_iterations) ?? DEFAULTS.max_iterations,
max_minutes: getNumber(parsedArgs.max_minutes) ?? DEFAULTS.max_minutes,
confirm_every: getNumber(parsedArgs.confirm_every) ?? DEFAULTS.confirm_every,
confirm_timeout: getNumber(parsedArgs.confirm_timeout) ?? DEFAULTS.confirm_timeout,
max_same_output: getNumber(parsedArgs.max_same_output) ?? DEFAULTS.max_same_output,
max_diff_lines: getNumber(parsedArgs.max_diff_lines) ?? DEFAULTS.max_diff_lines,
cooldown_seconds: getNumber(parsedArgs.cooldown_seconds) ?? DEFAULTS.cooldown_seconds,
};
// 检测操作系统
const isWindows = process.platform === "win32";
// 生成所有文件内容
const promptMd = generatePromptTemplate(params.goal, params.completion_promise, params.test_command);
const fixPlanMd = generateFixPlanTemplate(params.goal);
const progressMd = generateProgressTemplate();
const safeScript = isWindows
? generateSafeScriptWindows(params)
: generateSafeScript(params);
const normalScript = generateNormalScript(params);
const guide = generateGuide(params, isWindows);
// 组装输出
const scriptExt = isWindows ? "ps1" : "sh";
const output = `${guide}
---
## 📄 File Contents
### 1. PROMPT.md
\`\`\`markdown
${promptMd}
\`\`\`
---
### 2. @fix_plan.md
\`\`\`markdown
${fixPlanMd}
\`\`\`
---
### 3. PROGRESS.md
\`\`\`markdown
${progressMd}
\`\`\`
---
### 4. ralph_loop_safe.${scriptExt} (Safe Mode - Recommended)
\`\`\`${isWindows ? 'powershell' : 'bash'}
${safeScript}
\`\`\`
---
### 5. ralph_loop.sh (Normal Mode - Use with Caution)
\`\`\`bash
${normalScript}
\`\`\`
---
## ✅ Next Steps
1. Create \`.ralph/\` directory
2. Copy each file content above into respective files
3. Make scripts executable (if on Linux/Mac)
4. Review PROMPT.md and adjust if needed
5. Run \`ralph_loop_safe.${scriptExt}\`
6. Monitor progress and logs
**Happy coding! 🚀**
`;
return {
content: [{ type: "text", text: output }],
};
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
return {
content: [{ type: "text", text: `❌ start_ralph 执行失败: ${errorMsg}` }],
isError: true,
};
}
}