# ralphex configuration
# copy this file to ~/.config/ralphex/config and modify as needed
#
# config values in this file can be overridden by CLI flags.
# precedence (highest to lowest): CLI flags > local config (.ralphex/) > global config (~/.config/ralphex/) > embedded defaults
#
# NOTE: inline comments (e.g., "key = value # comment") are NOT supported.
# use full-line comments starting with # on a separate line instead.
# this is required to support hex color values like #00ff00.

# ------------------------------------------------------------------------------
# claude executor
# ------------------------------------------------------------------------------

# claude_command: the command to run claude code
# default: "claude"
claude_command = claude

# claude_args: arguments passed to claude command
# --dangerously-skip-permissions: bypass permission prompts for autonomous execution
# --output-format stream-json: output JSON events for progress tracking
# --verbose: enable detailed logging
claude_args = --dangerously-skip-permissions --output-format stream-json --verbose

# task_model: model to use for task execution
# syntax: model[:effort] where model is opus/sonnet/haiku (or a full model ID like
# claude-sonnet-4-5-20250929) and effort is low/medium/high/xhigh/max.
# either part is optional: "opus" sets model only, ":high" sets effort only,
# "opus:high" sets both. leave empty to use Claude CLI's defaults.
# task_model =

# review_model: model to use for review phases (first review, fix loops, finalize)
# same model[:effort] syntax as task_model.
# falls back to task_model if not set, then to Claude CLI's defaults.
# use a cheaper/faster model (e.g., sonnet) or lower effort for reviews to reduce cost.
# review_model =

# ------------------------------------------------------------------------------
# codex executor
# ------------------------------------------------------------------------------

# codex_enabled: whether to run codex external review phase
# set to false to skip codex review entirely
# default: true
codex_enabled = true

# codex_command: the command to run openai codex
# default: "codex"
codex_command = codex

# codex_model: model ID for codex
# available models: gpt-5.4, gpt-5.3-codex, gpt-5.3-codex-mini
# default: gpt-5.4
codex_model = gpt-5.4

# codex_reasoning_effort: reasoning effort level for codex
# available: low, medium, high, xhigh
# default: xhigh
codex_reasoning_effort = xhigh

# codex_timeout_ms: timeout for codex execution in milliseconds
# default: 3600000 (1 hour)
codex_timeout_ms = 3600000

# codex_sandbox: sandbox mode for codex execution
# available: read-only, workspace-write, danger-full-access
# read-only: codex can read files but not write (safest for code review)
# note: in docker, sandbox is auto-disabled (landlock doesn't work in containers)
# default: read-only
codex_sandbox = read-only

# ------------------------------------------------------------------------------
# external review
# ------------------------------------------------------------------------------

# external_review_tool: which tool to use for external code review
# available: codex, custom, none
# codex: use OpenAI Codex for external review (default)
# custom: use a custom script specified by custom_review_script
# none: skip external review entirely
# note: codex_enabled = false is treated as external_review_tool = none for backward compat
# default: codex
external_review_tool = codex

# custom_review_script: path to custom review script
# only used when external_review_tool = custom
# script receives prompt file path as single argument
# script should output findings to stdout and use <<<RALPHEX:CODEX_REVIEW_DONE>>> signal
# example: custom_review_script = ~/.config/ralphex/scripts/my-review.sh
# custom_review_script =

# ------------------------------------------------------------------------------
# finalize step
# ------------------------------------------------------------------------------

# finalize_enabled: whether to run finalize step after successful review phases
# runs once at the end, best-effort (failures logged but don't block success)
# default: false
# finalize_enabled = false

# ------------------------------------------------------------------------------
# claude authentication
# ------------------------------------------------------------------------------

# preserve_anthropic_api_key: when true, ANTHROPIC_API_KEY is passed through to
# the child claude process. enable this if you authenticate Claude Code via API
# key (ANTHROPIC_API_KEY) rather than OAuth/keychain login. by default the key
# is stripped so a host-set key cannot silently override OAuth credentials and
# bill a different account.
# default: false
# preserve_anthropic_api_key = false

# ------------------------------------------------------------------------------
# plan move behavior
# ------------------------------------------------------------------------------

# move_plan_on_completion: whether to move completed plan file into
# docs/plans/completed/ on success. set to false for workflows that
# manage plan file lifecycle externally (e.g. spec-driven tooling with
# separate archive steps).
# default: true
move_plan_on_completion = true

# ------------------------------------------------------------------------------
# worktree isolation
# ------------------------------------------------------------------------------

# use_worktree: run each plan in an isolated git worktree
# creates .ralphex/worktrees/<plan-name> for parallel execution
# default: false
# use_worktree = false

# ------------------------------------------------------------------------------
# timing
# ------------------------------------------------------------------------------

# iteration_delay_ms: delay between iterations in milliseconds
# allows for file system sync and prevents rate limiting
# default: 2000
iteration_delay_ms = 2000

# task_retry_count: number of retries if a task fails
# 0 = no retries, 1 = one retry (total 2 attempts)
# default: 1
task_retry_count = 1

# max_iterations: maximum task iterations per plan execution
# can also be set via --max-iterations CLI flag (CLI takes precedence)
# default: 50
# max_iterations = 50

# max_external_iterations: override external review iteration limit
# 0 = auto (derived from max_iterations as max(3, max_iterations/5))
# set to a positive value to use a fixed iteration count
# default: 0
# max_external_iterations = 0

# review_patience: terminate external review after N consecutive unchanged rounds
# when the external review tool and Claude can't agree on findings, the loop
# runs until max_external_iterations. set review_patience to break early when
# N consecutive rounds produce no commits (Claude wins the dispute).
# 0 = disabled (loop runs to max iterations)
# default: 0
# review_patience = 0

# session_timeout: maximum duration for a single claude session
# kills hanging sessions (e.g., agent started a blocking operation)
# uses Go duration format (e.g., "30m", "1h", "1h30m")
# omit or leave empty to disable (no timeout)
# session_timeout =

# idle_timeout: kill claude session after no output for this duration
# unlike session_timeout (fixed wall-clock limit), idle timeout resets on each
# output line and only fires when the session goes silent
# uses Go duration format (e.g., "5m", "10m", "30m")
# omit or leave empty to disable (no timeout)
# idle_timeout =

# ------------------------------------------------------------------------------
# paths
# ------------------------------------------------------------------------------

# plans_dir: directory where plan files are located
# relative paths are resolved from the project root
# default: docs/plans
plans_dir = docs/plans

# default_branch: override the auto-detected default branch used for code review
# by default, ralphex detects the default branch from origin/HEAD or fallbacks to main/master,
# set this to override for projects using non-standard branch names or Git flow
# default_branch = dev

# watch_dirs: directories to watch for progress files in dashboard mode
# comma-separated list of paths, relative paths resolved from project root
# if not specified, defaults to current working directory
# example: watch_dirs = /home/user/projects, /var/log/ralphex
# watch_dirs =

# ------------------------------------------------------------------------------
# version control
# ------------------------------------------------------------------------------

# vcs_command: the VCS command used by ralphex's git backend
# set to a custom script (e.g., ~/scripts/hg2git.sh) to use Mercurial
# the script receives the same arguments as git and must translate them
# default: git
vcs_command = git

# commit_trailer: trailer line appended to all ralphex-orchestrated git commits
# useful for attribution or tracking (e.g., Co-authored-by lines)
# example: commit_trailer = Co-authored-by: ralphex <noreply@ralphex.com>
# default: empty (disabled)
# commit_trailer =

# ------------------------------------------------------------------------------
# error pattern detection
# ------------------------------------------------------------------------------

# claude_error_patterns: patterns to detect in claude output indicating errors
# comma-separated list of substrings (case-insensitive matching)
# when detected, ralphex exits gracefully with an informative message
# default: You've hit your limit,API Error:,cannot be launched inside another Claude Code session,Not logged in,Your usage allocation has been disabled by your admin,You've hit your org's monthly usage limit
claude_error_patterns = You've hit your limit,API Error:,cannot be launched inside another Claude Code session,Not logged in,Your usage allocation has been disabled by your admin,You've hit your org's monthly usage limit

# codex_error_patterns: patterns to detect in codex output indicating errors
# comma-separated list of substrings (case-insensitive matching)
# when detected, ralphex exits gracefully with an informative message
# default: Rate limit exceeded,rate limit reached,429 Too Many Requests,quota exceeded,insufficient_quota,You've hit your usage limit
codex_error_patterns = Rate limit exceeded,rate limit reached,429 Too Many Requests,quota exceeded,insufficient_quota,You've hit your usage limit

# ------------------------------------------------------------------------------
# rate limit wait and retry
# ------------------------------------------------------------------------------

# claude_limit_patterns: patterns to detect rate limits in claude output
# comma-separated list of substrings (case-insensitive matching)
# when detected AND wait_on_limit is set, ralphex waits and retries
# when detected WITHOUT wait_on_limit, falls through to error pattern behavior
# default: You've hit your limit,Your usage allocation has been disabled by your admin,You've hit your org's monthly usage limit
claude_limit_patterns = You've hit your limit,Your usage allocation has been disabled by your admin,You've hit your org's monthly usage limit

# codex_limit_patterns: patterns to detect rate limits in codex/external output
# comma-separated list of substrings (case-insensitive matching)
# same retry behavior as claude_limit_patterns
# default: Rate limit exceeded,rate limit reached,429 Too Many Requests,quota exceeded,insufficient_quota,You've hit your usage limit
codex_limit_patterns = Rate limit exceeded,rate limit reached,429 Too Many Requests,quota exceeded,insufficient_quota,You've hit your usage limit

# wait_on_limit: duration to wait before retrying after a rate limit is detected
# uses Go duration format (e.g., "1h", "30m", "1h30m", "90s")
# omit to inherit global value; set to 0s to explicitly disable inherited setting
# wait_on_limit =

# ------------------------------------------------------------------------------
# notifications (optional, disabled by default)
# ------------------------------------------------------------------------------

# notify_channels: comma-separated list of channels to use
# available: telegram, email, slack, webhook, custom
# leave empty or omit to disable notifications entirely
# example: notify_channels = telegram, webhook
# notify_channels =

# notify_on_error: send notification when execution fails
# default: true
# notify_on_error = true

# notify_on_complete: send notification when execution succeeds
# default: true
# notify_on_complete = true

# notify_timeout_ms: total timeout for all notification channels in milliseconds
# default: 10000
# notify_timeout_ms = 10000

# --- telegram ---

# notify_telegram_token: bot token from BotFather
# notify_telegram_token =

# notify_telegram_chat: chat ID or channel name (e.g., @mychannel or 123456789)
# notify_telegram_chat =

# --- slack ---

# notify_slack_token: slack bot oauth token (xoxb-...)
# notify_slack_token =

# notify_slack_channel: channel name or ID to post to
# notify_slack_channel =

# --- email (SMTP) ---

# notify_smtp_host: SMTP server hostname
# notify_smtp_host =

# notify_smtp_port: SMTP server port
# default: 587
# notify_smtp_port = 587

# notify_smtp_username: SMTP authentication username
# notify_smtp_username =

# notify_smtp_password: SMTP authentication password
# notify_smtp_password =

# notify_smtp_starttls: use STARTTLS for SMTP connection
# default: false
# notify_smtp_starttls = false

# notify_email_from: sender email address
# notify_email_from =

# notify_email_to: comma-separated list of recipient email addresses
# notify_email_to =

# --- webhook ---

# notify_webhook_urls: comma-separated list of webhook endpoint URLs
# the notification message is POSTed as plain text to each URL
# notify_webhook_urls =

# --- custom script ---

# notify_custom_script: path to custom notification script
# script receives Result JSON on stdin, exit 0 = success, non-zero = failure
# timeout controlled by notify_timeout_ms
# example: notify_custom_script = ~/.config/ralphex/scripts/notify.sh
# notify_custom_script =

# ------------------------------------------------------------------------------
# output colors (hex format: #RRGGBB)
# ------------------------------------------------------------------------------

# color_task: task execution phase (green)
color_task = #2e8b57

# color_review: review phase (teal)
color_review = #1a9e9e

# color_codex: codex external review (purple)
color_codex = #9b59b6

# color_claude_eval: claude evaluation of codex output (blue)
color_claude_eval = #5b8dd9

# color_warn: warning messages (amber)
color_warn = #d4930d

# color_error: error messages (red)
color_error = #cc0000

# color_signal: completion/failure signals (red)
color_signal = #d25252

# color_timestamp: timestamp prefix (gray)
color_timestamp = #707070

# color_info: informational messages (gray)
color_info = #808080
