Skip to content

Hooks

Hooks execute shell commands at key points during the agent loop. Use them to integrate with external tools, send notifications, run tests, or trigger custom workflows.

Add hooks to .ralph/config.toml:

[hooks]
ralph_start = "echo 'Starting Ralph'"
ralph_loop_start = "echo 'Iteration $RALPH_LOOP_ITERATION starting'"
ralph_loop_end = "npm test --bail || true"
ralph_complete = "notify-send 'Ralph finished!'"
ralph_max_iterations = "echo 'Max iterations reached'"
HookWhen It Runs
ralph_startOnce at the beginning, before the first iteration
ralph_loop_startAt the start of each iteration
ralph_loop_endAt the end of each iteration
ralph_completeWhen the task completes successfully
ralph_max_iterationsWhen max iterations reached without completion
ralph run
├─► ralph_start
├─► ralph_loop_start ─┐
│ [AI iteration] │ repeats
├─► ralph_loop_end ─┘
└─► ralph_complete (success)
OR ralph_max_iterations (limit reached)

Each hook receives context via environment variables.

VariableDescription
RALPH_CWDWorking directory
RALPH_TASKS_NOT_PASSINGNumber of failing tasks from PRD
RALPH_MAX_ITERATIONSMaximum iterations configured
VariableDescription
RALPH_CWDWorking directory
RALPH_LOOP_ITERATIONCurrent iteration number (1-indexed)
VariableDescription
RALPH_CWDWorking directory
RALPH_TOTAL_ITERATIONSTotal iterations executed

Catch regressions early by running tests after each iteration:

[hooks]
ralph_loop_end = "bun test --bail 2>/dev/null || true"

The || true prevents hook failure from stopping Ralph.

Send a Slack message when Ralph completes:

[hooks]
ralph_complete = """
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Ralph completed in '$RALPH_TOTAL_ITERATIONS' iterations"}' \
$SLACK_WEBHOOK_URL
"""

Track iteration timing for analysis:

[hooks]
ralph_loop_start = "echo \"$(date): Starting iteration $RALPH_LOOP_ITERATION\" >> ralph.log"
ralph_loop_end = "echo \"$(date): Finished iteration $RALPH_LOOP_ITERATION\" >> ralph.log"

Get notified when Ralph finishes:

[hooks]
ralph_complete = "osascript -e 'display notification \"Completed in $RALPH_TOTAL_ITERATIONS iterations\" with title \"Ralph\"'"
ralph_max_iterations = "osascript -e 'display notification \"Max iterations reached\" with title \"Ralph\" sound name \"Basso\"'"

Audio feedback for completion status:

[hooks]
ralph_complete = "afplay /System/Library/Sounds/Glass.aiff"
ralph_max_iterations = "afplay /System/Library/Sounds/Basso.aiff"

Auto-fix code style before each iteration:

[hooks]
ralph_start = "npm run lint:fix"
ralph_loop_end = "npm run format"

Auto-commit after each successful iteration:

[hooks]
ralph_loop_end = """
git add -A && \
git commit -m "ralph: iteration $RALPH_LOOP_ITERATION" --allow-empty || true
"""

  • Commands run via sh -c in the configured working directory
  • Hooks run synchronously and block the loop until complete
  • All parent process environment variables are inherited
  • Hook failures (non-zero exit code) are logged but don’t stop Ralph
  • Use || true to suppress expected failures
  • Enable verbose = true in config to see hook execution logs

Enable verbose mode to see hook execution:

verbose = true

Or via CLI:

Terminal window
ralph run --verbose

Use CaseHookExample
Pre-flight checksralph_startValidate environment, install deps
Code qualityralph_loop_endRun linter, formatter, tests
Progress trackingralph_loop_start/endLog to file, update dashboard
Notificationsralph_completeSlack, email, desktop alert
Alertsralph_max_iterationsNotify that manual review needed
Version controlralph_loop_endAuto-commit checkpoints