| name | ralph-x |
| description | Build and run an AI development loop โ collects pipeline, iterations, checklist, skills via conversation, then generates and executes a staged claude -p loop |
| argument-hint | [PROMPT] |
| allowed-tools | ["Read","Write","Bash","Glob","Grep"] |
Ralph-X: AI Development Loop Generator
Respond in the same language the user uses. Korean โ Korean. English โ English.
์ธ์
์์ ์ ์๋ ๋ง์ด๊ทธ๋ ์ด์
์คํฌ์ด ํธ์ถ๋๋ฉด ๊ฐ์ฅ ๋จผ์ ์๋ ์ฝ๋๋ฅผ ์คํํ๋ค (์ฌ์ฉ์ ํ์ธ ์์ด ์๋):
python3 -c "
import os, shutil
old = '.claude/ralph-x-runs'
new = 'ralph-x-runs'
if os.path.isdir(old):
os.makedirs(new, exist_ok=True)
for item in os.listdir(old):
src = os.path.join(old, item)
dst = os.path.join(new, item)
if not os.path.exists(dst):
shutil.move(src, dst)
if not os.listdir(old):
os.rmdir(old)
print('migrated')
"
์ถ๋ ฅ์ด migrated์ด๋ฉด: ".claude/ralph-x-runs/์ ralph-x-runs/๋ก ์๋ ์ด๋ํ์ต๋๋ค." ํ ์ค ์๋ด.
ํ์ผ์ด ์์ผ๋ฉด ์กฐ์ฉํ ๋์ด๊ฐ๋ค.
What You Do
You help the user build a multi-step claude -p loop. Collect requirements via conversation, generate a bash script, then auto-run it in background.
Flow
Step 1: Task (if not provided as argument)
Ask: "What task should I work on? / ์ด๋ค ์์
์ ํ ๊น์?"
Step 1-B: Execution Mode
Ask: "์คํ ๋ฐฉ์์ ์ ํํ์ธ์ / Choose execution mode:
- claude-p ๋ฃจํ โ ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํฌ๋ฆฝํธ ์คํ (๊ธฐ๋ณธ๊ฐ)
- in-session โ ํ์ฌ ๋ํ์์ ์ง์ ์คํ"
๊ธฐ๋ณธ๊ฐ: 1 (claude-p)
Step 2: Pipeline
First, check if ralph-x-runs/presets.json exists and has entries.
Show the pipeline menu. If presets exist, append them after a separator:
์ด๋ป๊ฒ ์งํํ ๊น์? / How do you want to proceed?
1. ๐ Quick โ ๋ฐ๋ก ์คํ (single step)
2. ๐ Standard โ ๋ถ์ โ ๊ฐ๋ฐ โ ๊ฒ์ฆ
3. ๐ฌ Thorough โ ๋ถ์ โ ์ค๊ณ โ ๊ฐ๋ฐ โ ๋ฆฌ๋ทฐ โ ํ
์คํธ
4. ๐ฏ Custom โ ์ง์ ์คํ
์กฐํฉ
โโโโโโโโโโโโโโโโโโโโโโโโโ
5. kaggle-churn
โ ๋ถ์ โ "๊ฒฝ์ ์๋ฃจ์
์์ 10๊ฐ ๋ถ์" (/browse)
โก ๊ฐ๋ฐ โ "LightGBM baseline ๊ตฌํ"
โข ๊ฒ์ฆ โ "CV ์ ์ ํ์ธ ํ submission ์์ฑ" (/test)
6. web-scraper
โ ๋ถ์ โ "ํ๊ฒ ์ฌ์ดํธ ๊ตฌ์กฐ ํ์
"
โก ๊ฐ๋ฐ โ "์
๋ ๋์์ผ๋ก ํฌ๋กค๋ฌ ๊ตฌํ" (/browse)
Preset display format: For each preset, show steps numbered with circled digits (โ โกโข...).
Each step line: โ {step name} โ "{task_template or step description, truncated ~30 chars}" (/skill-name)
- Only show
(/skill-name) if the step has a non-null skill
- Truncate prompt/description to ~30 chars with
โฆ if longer
If user selects a preset (5, 6, ...): load preset config, skip to Step 2-B (claude-p ๋ชจ๋์ผ ๋๋ง) with preset's model as default, then Step 3 with preset's max_iterations as default, then Step 4 with preset's checklist pre-filled. Confirm and run.
If no presets exist, show only options 1-4.
If Custom: collect steps one by one ("Step 1?", "Step 2?", ... until "done"/"๋")
Each step becomes a SEPARATE claude -p call.
Ask if there's a skill to use per step (e.g., /browse, /review, /test, or skip)
Step 2-B: Model (claude-p ๋ชจ๋์ผ ๋๋ง / skip if in-session)
Ask: "์ด๋ค ๋ชจ๋ธ๋ก ๋๋ฆด๊น์? (๊ธฐ๋ณธ: sonnet) / Which model? (default: sonnet)"
Options:
sonnet (default)
opus
haiku
- or full model name (e.g.,
claude-sonnet-4-6)
Step 3: Iterations
Ask: "์ต๋ ๋ช ํ ๋ฐ๋ณต? (๊ธฐ๋ณธ 10) / Max iterations? (default 10)"
Step 4: Completion Checklist
Ask: "์๋ฃ ์กฐ๊ฑด์ ํ๋์ฉ ์๋ ค์ฃผ์ธ์ (๋๋๋ฉด '๋') / Add completion conditions one by one (say 'done' when finished)"
Collect items until done. This becomes a checklist in the prompt.
Step 5: Confirm & Generate
Show summary:
Task: ...
Model: sonnet
Pipeline: Step1 โ Step2 โ Step3
Iterations: 20
์คํ ๋ฐฉ์: ํ์ฌ ์ธ์
(๋๋ claude-p ๋ฃจํ)
Checklist:
- [ ] condition 1
- [ ] condition 2
Skills: /browse (Step1), /test (Step3)
Ask to confirm. Then proceed to Step 5-B.
Step 5-B: Run Directory Setup
After user confirms, before generating the script:
-
Generate RUN_ID from task name:
- Slugify: lowercase, spaces/special chars โ hyphens, max 20 chars
- If using a preset, use the preset name as RUN_ID
- Examples: "์ ํ๋ธ ์์ด๋์ด ๊ฒ์ฆ" โ
youtube-idea-verify, "Kaggle trial" โ kaggle-trial
-
Set RUN_DIR: ralph-x-runs/{RUN_ID}
-
Check for collision: If RUN_DIR already exists, append suffix: -2, -3, etc.
RUN_ID="<slug>"
RUN_DIR="ralph-x-runs/$RUN_ID"
if [ -d "$RUN_DIR" ]; then
i=2
while [ -d "ralph-x-runs/${RUN_ID}-${i}" ]; do i=$((i+1)); done
RUN_ID="${RUN_ID}-${i}"
RUN_DIR="ralph-x-runs/$RUN_ID"
fi
-
Check for running processes in this project:
ps aux | grep "ralph-x-runs" | grep "$(pwd)" | grep -v grep
If found, warn the user:
โ ๏ธ ์ด ํ๋ก์ ํธ์์ ์ด๋ฏธ Ralph-X ๋ฃจํ๊ฐ ์คํ ์ค์
๋๋ค.
1. ๊ธฐ์กด ๋ฃจํ ์ค๋จํ๊ณ ์๋ก ์์
2. ๊ธฐ์กด ๋ฃจํ ์ ์งํ๊ณ ์ ๋ฐ ์ถ๊ฐ (๋ณ๋ ฌ)
3. ์ทจ์
-
.gitignore์ ralph-x-runs/ ์๋ ์ถ๊ฐ (์์ผ๋ฉด ์์ฑ):
if ! grep -qxF 'ralph-x-runs/' .gitignore 2>/dev/null; then
echo 'ralph-x-runs/' >> .gitignore
fi
Step 6: Generate Script
Write prompts to temp files (one per step), then call claude -p "$(cat file)" for each.
Each step uses a UNIQUE heredoc delimiter (S1EOF, S2EOF, S3EOF, ...).
CRITICAL: NEVER use --max-turns. Each step runs until it finishes on its own.
Create {RUN_DIR}/run.sh (NOT .claude/ralph-x-run.sh):
#!/bin/bash
set -euo pipefail
RUN_DIR="ralph-x-runs/<run_id>"
MODEL="<model>"
LOG_FILE="$RUN_DIR/log.md"
CHECKLIST_FILE="$RUN_DIR/checklist.md"
if [ ! -f "$LOG_FILE" ]; then
cat > "$LOG_FILE" << 'LOGEOF'
Task: <task>
Started: <timestamp>
LOGEOF
fi
if [ ! -f "$CHECKLIST_FILE" ]; then
cat > "$CHECKLIST_FILE" << 'CHECKEOF'
- [ ] condition 1
- [ ] condition 2
CHECKEOF
fi
MAX_ITER=<N>
PROMPT_DIR="$RUN_DIR/prompts"
mkdir -p "$PROMPT_DIR"
cat > "$PROMPT_DIR/step1.txt" << 'S1EOF'
You are in a Ralph-X loop.
Task: <task>
Current step: <step 1 description>
<skill instruction if any, e.g. "Use /browse skill to crawl ...">
- Read {RUN_DIR}/log.md previous work
- Work autonomously. Do NOT ask questions.
- Append your summary to {RUN_DIR}/log.md when .
S1EOF
> <<
You are a Ralph-X loop.
Task: <task>
Current step: <step 2 description>
- Read {RUN_DIR}/log.md previous work
- Work autonomously. Do NOT ask questions.
- Append your summary to {RUN_DIR}/log.md when .
S2EOF
> <<
You are a Ralph-X loop.
Task: <task>
Current step: <step 3 description>
- Read {RUN_DIR}/log.md previous work
- Read {RUN_DIR}/checklist.md remaining conditions
- Work autonomously. Do NOT ask questions.
- Append your summary to {RUN_DIR}/log.md when .
- If a checklist item is , mark it [x] {RUN_DIR}/checklist.md
S3EOF
i $( 1 );
[ -f ] && ! grep -q 2>/dev/null;
claude -p --model
claude -p --model
claude -p --model
For conditional steps (e.g., "every 3 iterations"), wrap in an if:
if [ $((i % 3)) -eq 0 ]; then
claude -p --model "$MODEL" "$(cat "$PROMPT_DIR/step4.txt")"
fi
Step 7: Execute
Branch on execution mode chosen in Step 1-B.
Step 7-A: claude-p ๋ฃจํ (๊ธฐ๋ณธ)
- Auto-save preset to
ralph-x-runs/presets.json (no confirmation)
- Auto-run in background: Use Bash tool with
run_in_background: true to run bash {RUN_DIR}/run.sh
- Report: "์คํ ์์ํ์ต๋๋ค. ์คํฌ๋ฆฝํธ:
{RUN_DIR}/run.sh"
Do NOT ask "์คํํ ๊น์?" โ just run it.
Step 7-B: ํ์ฌ ์ธ์
์คํ (in-session)
-
session_id ์ฆ์ ์บก์ฒ (Bash):
SESSION_ID=$(ls -lt ~/.claude/worklogs/.collecting/*.jsonl 2>/dev/null \
| awk 'NR==1{print $NF}' | xargs basename | sed 's/\.jsonl//')
[ -z "$SESSION_ID" ] && SESSION_ID=$(ls -t ~/.claude/session-env/ 2>/dev/null | head -1)
echo "$SESSION_ID"
-
mkdir -p {RUN_DIR}
-
Write tool๋ก {RUN_DIR}/session-state.json ์์ฑ:
{
"active": true,
"session_id": "<SESSION_ID>",
"run_id": "<RUN_ID>",
"run_dir": "ralph-x-runs/<RUN_ID>",
"checklist_file": "ralph-x-runs/<RUN_ID>/checklist.md",
"current_iteration": 0,
"max_iterations": <N>
}
-
Write tool๋ก {RUN_DIR}/checklist.md ์์ฑ (์์งํ ์๋ฃ ์กฐ๊ฑด๋ค):
- [ ] condition 1
- [ ] condition 2
-
Write tool๋ก {RUN_DIR}/log.md ์์ฑ (์ด๊ธฐํ):
# Ralph-X Work Log
Task: <task>
Mode: in-session
์ค์: in-session ๋ชจ๋์์๋ stop hook(ralph-x-gate.sh)์ด session-state.json์ ๊ฐ์ํ๋ค.
checklist ๋ฏธ์ + iter < max ์ํ์์ ๋ํ ์ข
๋ฃ ์๋ ์ ์๋์ผ๋ก ์ฐจ๋จ๋๋ค.
Preset System
After generating, ALWAYS auto-save to ralph-x-runs/presets.json:
{
"preset-name": {
"model": "sonnet",
"task_template": "...",
"steps": [
{"name": "...", "skill": "/browse or null"},
{"name": "...", "skill": null},
{"name": "...", "skill": null, "every_n": 3}
],
"max_iterations": 20,
"checklist": ["condition 1"
On next /ralph-x invocation, check for presets. If presets exist, append them to the Step 2 pipeline menu after a separator line (โโโโโ). Number them continuously (5, 6, 7, ...). Each preset shows its steps with detail:
5. preset-name
โ step-name โ "prompt excerpt ~30chars" (/skill-name)
โก step-name โ "prompt excerpt ~30chars"
- Show skill in parentheses after prompt excerpt, only if skill is not null
- Truncate
task_template to ~30 chars for the prompt excerpt. If step has a dedicated description in steps[].name, use that as the step name.
- If user selects a preset number, skip to Step 2-B (claude-p ๋ชจ๋์ผ ๋๋ง) with preset's model as default, then Step 3 with preset's max_iterations as default, then Step 4 with preset's checklist pre-filled. Confirm and run.
Rules
claude-p ๋ชจ๋ (Step 7-A)
- Do NOT start working on the task. You ONLY build the script and run it.
- Each step = one
claude -p call. NEVER combine multiple steps into one call.
- NEVER use
--max-turns on any claude -p call.
- Use UNIQUE heredoc delimiters per step (S1EOF, S2EOF, S3EOF, ...). NEVER reuse delimiters.
- Write prompts to temp files first, then
claude -p "$(cat file)". Do NOT inline heredocs inside the for loop.
- Keep step prompts SHORT and SINGLE-PURPOSE.
- Always include log file read/write instructions in each step prompt (use
{RUN_DIR}/log.md).
- Always include checklist check in each step prompt (use
{RUN_DIR}/checklist.md).
- Step output files go in RUN_DIR:
{RUN_DIR}/stage1.md, {RUN_DIR}/stage2.md, etc.
- Auto-save preset after generation. Do NOT ask.
- Auto-run in background after generation. Do NOT ask.
in-session ๋ชจ๋ (Step 7-B)
- session_id๋ฅผ ์บก์ฒํ ์ฆ์ session-state.json์ ๊ธฐ๋กํ๋ค. ๋์ค์ผ๋ก ๋ฏธ๋ฃจ์ง ์๋๋ค.
- ๋ฃจํ ์ค claude -p ํธ์ถ ๊ธ์ง. ํ์ฌ ๋ํ ์ปจํ
์คํธ์์ ์ง์ ์ํํ๋ค.
- ๋งค iteration ํ ๋ฐ๋์ session-state.json์ current_iteration์ ์
๋ฐ์ดํธํ๋ค. (stop hook์ด ์ด ๊ฐ์ผ๋ก ์ฐจ๋จ ์ฌ๋ถ ํ๋จ)
- checklist ํญ๋ชฉ ์๋ฃ ์ ์ฆ์
[ ] โ [x] ๋ก ๊ฐฑ์ ํ๋ค.
- ๋ฃจํ ์๋ฃ ํ ๋ฐ๋์ active=false ์ฒ๋ฆฌํ๋ค. (๋ฏธ์ฒ๋ฆฌ ์ stop hook์ด ๊ณ์ ์ฐจ๋จ)
in-session ๋ชจ๋ โ ์ ๋ ๋ฉ์ถ์ง ์๋๋ค (ํ์ ๊ท์น)
ralph-x in-session ๋ฃจํ๋ ์ข
๋ฃ ์กฐ๊ฑด ๋๋ฌ ์ ๊น์ง ์ ๋ ๋ฉ์ถ์ง ์๋๋ค.
์ข
๋ฃ ์กฐ๊ฑด์ ๋จ ๋ ๊ฐ์ง (๋ ๋ค ์ถฉ์กฑ ํ์ X โ ๋ ์ค ํ๋๋ผ๋):
session-state.json์ current_iteration >= max_iterations
checklist.md์ ๋ชจ๋ ํญ๋ชฉ [x]
๊ทธ ์ธ ์ด๋ค ์ํฉ์์๋ ๋ฃจํ๋ฅผ ๋ฉ์ถ์ง ์๋๋ค. ๊ฒฐ๊ณผ๊ฐ fail์ด๋ , ๊ฐ์ค์ด ๋งํ ๋ณด์ด๋ , ์ฌ์ฉ์๊ฐ ์ง๋ฌธ/comment๋ฅผ ๋ณด๋ด๋ โ ๋ฌด์กฐ๊ฑด ๊ฐ์ ์๋ต ์์์ ๋ค์ iter๋ฅผ Write/Bash๋ก ์ฆ์ ์งํํ๋ค.
๊ธ์ง ํ๋:
- "์ด๋ป๊ฒ ๊ฐ์ง ์ ํด์ฃผ๋ฉด", "์ด๋ค ๋ฐฉํฅ์ผ๋ก?", "๊ณ์ ์งํํ ๊น์?", "์ด๊ฑฐ ์๋ฏธ ์๋" ๋ฑ ์ฌ์ฉ์ ์ปจํ ์์ฒญ
- ๊ฒฐ๊ณผ ๋ณด๊ณ ํ ์๋ต ์ข
๋ฃ (์ฌ์ฉ์ ๋ต ๊ธฐ๋ค๋ฆฌ๊ธฐ)
- fail N๊ฐ ๋์ ํ "๋จ์ X๊ฐ ๊ฐ์ ํจํด ๋ฐ๋ณต ๋ฌด์๋ฏธ" ์์ฒด ํ๋จ์ผ๋ก ๋ฉ์ถค
- "๋ฐฉํฅ ์ ํ ํ์", "๋ ์๋ํด๋ ๋ฌด์๋ฏธํ ๊ฒ" ๊ฐ์ ๋ฉํ ํ๋จ์ผ๋ก ์ ์ง
- ๊ฐ์ ์๋ต์์ ๊ฒฐ๊ณผ ๋ณด๊ณ ๋ง ํ๊ณ ๋ค์ iter ์ฝ๋ ์ ์ฐ๋ ํ์
ํ์ ํ๋:
- ๊ฒฐ๊ณผ ์งง๊ฒ ๋ณด๊ณ โ ๊ฐ์ ์๋ต ์์์ ๋ค์ iter Write/Bash ์ฆ์ ์คํ
- ๊ฐ์ค ๋งํ๋ฉด ์๋ ์ ํ ์์ญ ์์ฒด ๋ฐ๊ตด (์ฌ์ฉ์ ์ ๋ฌป๊ณ ): ๋ค๋ฅธ ์์ฐ๊ตฐ, ๋ค๋ฅธ timeframe, ๋ค๋ฅธ confirm ์ธ์, ๋งคํฌ๋ก ์ด๋ฒคํธ, ํ์ด ํต๊ณ์ฐจ์ต, ML ๋ถ๋ฅ ๋ฑ
- ์์ ํ์ํ๋ฉด ์์ฒด ํ๋จ์ผ๋ก ์์
- ๊ฒฐ๊ณผ ์ง๋ด๊ธฐ (์๋ฏธ ์๋ ๋ฐ๊ฒฌ ์์ฒด ํ๋จ ํ log.md/checklist.md์ ๊ธฐ๋ก)
why: ์ฌ์ฉ์๊ฐ ๋ช
์์ ์ผ๋ก ๋ฐ์ ๋ฃฐ โ "๊ฐฏ์+์ฒดํฌ๋ฆฌ์คํธ ๋ค ์ฑ์ธ ๋๊น์ง ์ฌ์ฉ์ ์ปจํ ์ ๋ ๋ฐ์ง ๋ง๊ณ ๋ ์์์ ํ๋จยท์์ ยท๊ฒฐ๊ณผ ๋ด๋ผ". ์ด ๋ฃฐ์ ์ด๊ธฐ๊ณ ๋ฉ์ถ๋ฉด ์ฌ์ฉ์๊ฐ ๋งค๋ฒ ์ง์ฆ๋ด๊ณ ๊ฐ์ ์ง์ ๋ฐ๋ณต. stop hook ์ธํ๋ผ(ralph-x-gate.sh)๋ LLM์ด ๋ฉ์ถ ๋ "๊ณ์ ์งํ" ๋ฉ์์ง๋ฅผ ๋์ฐ์ง๋ง, LLM ์์ฒด๊ฐ "fail ๋์ โ ์๋ฏธ ์์ โ ์ฌ์ฉ์ ์ปจํ" ํจํด์ผ๋ก ์์ฒด ์ ์งํ๋ฉด hook์ผ๋ก ๋ชป ๋ง๋๋ค. ๋ฐ๋ผ์ LLM ๋ฃฐ ๊ฐ์ .