Last active
January 23, 2026 21:15
-
-
Save markomitranic/547f0a798dcb1fdeb2384eff6f8fcb38 to your computer and use it in GitHub Desktop.
Ralph loop for Opencode. Because everything currently out there sucks :(
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -o pipefail | |
| PLANNER_MESSAGE=$(cat <<'EOF' | |
| @./PRD.md @./.ralph-progress.md | |
| 1. You are a strategic task planning agent. You do not implement tasks and edit the code, you just research, and write down the plan for the next AI Agent to implement. | |
| 2. Read the context files in `PRD.md` and `.ralph-progress.md`. | |
| 3. Pick the first available task that has not yet been marked as complete in the `PRD.md` file. | |
| 4. Start your plan with the task name and a description of the feature. | |
| IMPORTANT: You run in **non-interactive mode**: | |
| - Never ask the user for input or clarification | |
| - Never offer follow-up tasks or suggestions | |
| - Exit immediately after writing the plan. | |
| EOF | |
| ) | |
| BUILDER_MESSAGE=$(cat <<'EOF' | |
| @./PRD.md @./.ralph-progress.md @./.ralph-plan.md | |
| 1. You are a task implementation agent. Read the instructions in `.ralph-plan.md`. | |
| 2. If there is no instructions in `.ralph-plan.md`, exit immediately with an error!!! | |
| 3. Implement the feature described in `.ralph-plan.md`. | |
| 4. Verify your changes as described in `PRD.md`. Do all testing a human would do. A task CANNOT be complete until all testing requirements are met. | |
| 5. Update `PRD.md` and check-off the task as complete. Do not modify any other tasks. | |
| 6. Append to `.ralph-progress.md`. Include: task name, brief description, key changes and learnings. Keep entries concise but informative for the next agent/developer, sacrifice grammar for brevity. | |
| 7. Stage and Commit all modified files using git. **COMMIT ONLY** - never push! | |
| IMPORTANT: You run in **non-interactive mode**: | |
| - Never ask the user for input or clarification | |
| - Never offer follow-up tasks or suggestions | |
| - Exit immediately after completing the feature. | |
| EOF | |
| ) | |
| # Max Loops MUST be provided as a positive integer. | |
| skip_planning=false | |
| max_loops="" | |
| for arg in "$@"; do | |
| case "$arg" in | |
| --continue) | |
| skip_planning=true | |
| ;; | |
| *) | |
| if [ -n "$max_loops" ]; then | |
| echo "Usage: $(basename "$0") <max-loops> [--continue]" >&2 | |
| exit 1 | |
| fi | |
| max_loops="$arg" | |
| ;; | |
| esac | |
| done | |
| if [ -z "$max_loops" ]; then | |
| echo "Usage: $(basename "$0") <max-loops> [--continue]" >&2 | |
| exit 1 | |
| fi | |
| if [ -n "$max_loops" ] && { ! [[ "$max_loops" =~ ^[0-9]+$ ]] || [ "$max_loops" -le 0 ]; }; then | |
| echo "Usage: $(basename "$0") <max-loops> [--continue]" >&2 | |
| exit 1 | |
| fi | |
| count=1 | |
| run_once() { | |
| rm -rf .ralph-done | |
| touch .ralph-progress.md | |
| if [ ! -s PRD.md ]; then | |
| echo "PRD.md missing or empty; aborting." >&2 | |
| return 1 | |
| fi | |
| if [ "$skip_planning" = false ]; then | |
| echo "## PLANNING PHASE ##" | |
| OPENCODE_PERMISSION='{"*":"allow"}' opencode run ./ \ | |
| --model openai/gpt-5.2-codex \ | |
| --variant high \ | |
| --file ./PRD.md ./.ralph-progress.md \ | |
| --agent plan "$PLANNER_MESSAGE" | tee ./.ralph-plan.md | |
| if [ ! -s ./.ralph-plan.md ]; then | |
| echo "Plan missing or empty; aborting." >&2 | |
| return 1 | |
| fi | |
| fi | |
| echo "## IMPLEMENTATION PHASE ##" | |
| OPENCODE_PERMISSION='{"*":"allow"}' opencode run ./ \ | |
| --model openai/gpt-5.2-codex \ | |
| --variant high \ | |
| --file ./PRD.md ./.ralph-progress.md ./.ralph-plan.md \ | |
| --agent build "$BUILDER_MESSAGE" | |
| rm -rf ./.ralph-plan.md | |
| } | |
| # Run the loop until .ralph-done is found or max loops is reached. | |
| while [ "$count" -le "$max_loops" ]; do | |
| if [ -f .ralph-done ]; then | |
| echo ".ralph-done found; exiting." | |
| exit 0 | |
| fi | |
| echo "## RALPH LOOP $count/$max_loops ##" | |
| run_once | |
| status=$? | |
| if [ "$status" -ne 0 ]; then | |
| echo "ralph failed (exit $status); aborting." >&2 | |
| exit "$status" | |
| fi | |
| if [ -f .ralph-done ]; then | |
| echo ".ralph-done found; exiting." | |
| exit 0 | |
| fi | |
| count=$((count + 1)) | |
| done | |
| echo "Reached max loops ($max_loops) without .ralph-done; exiting." >&2 | |
| exit 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment