Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions ralph.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,40 +39,50 @@ PROGRESS_FILE="$SCRIPT_DIR/progress.txt"
ARCHIVE_DIR="$SCRIPT_DIR/archive"
LAST_BRANCH_FILE="$SCRIPT_DIR/.last-branch"

# ------------------------------------------------------------
# Fail fast on malformed PRDs before starting the agent loop
# ------------------------------------------------------------
if [ -f "$SCRIPT_DIR/scripts/validate_prd.sh" ]; then
"$SCRIPT_DIR/scripts/validate_prd.sh" "$PRD_FILE"
fi

# ------------------------------------------------------------
# Archive previous run if branch changed
# ------------------------------------------------------------
if [ -f "$PRD_FILE" ] && [ -f "$LAST_BRANCH_FILE" ]; then
CURRENT_BRANCH=$(jq -r '.branchName // empty' "$PRD_FILE" 2>/dev/null || echo "")
LAST_BRANCH=$(cat "$LAST_BRANCH_FILE" 2>/dev/null || echo "")

if [ -n "$CURRENT_BRANCH" ] && [ -n "$LAST_BRANCH" ] && [ "$CURRENT_BRANCH" != "$LAST_BRANCH" ]; then
# Archive the previous run
DATE=$(date +%Y-%m-%d)
# Strip "ralph/" prefix from branch name for folder
FOLDER_NAME=$(echo "$LAST_BRANCH" | sed 's|^ralph/||')
ARCHIVE_FOLDER="$ARCHIVE_DIR/$DATE-$FOLDER_NAME"

echo "Archiving previous run: $LAST_BRANCH"
mkdir -p "$ARCHIVE_FOLDER"
[ -f "$PRD_FILE" ] && cp "$PRD_FILE" "$ARCHIVE_FOLDER/"
[ -f "$PROGRESS_FILE" ] && cp "$PROGRESS_FILE" "$ARCHIVE_FOLDER/"
echo " Archived to: $ARCHIVE_FOLDER"

# Reset progress file for new run

echo "# Ralph Progress Log" > "$PROGRESS_FILE"
echo "Started: $(date)" >> "$PROGRESS_FILE"
echo "---" >> "$PROGRESS_FILE"
fi
fi

# ------------------------------------------------------------
# Track current branch
# ------------------------------------------------------------
if [ -f "$PRD_FILE" ]; then
CURRENT_BRANCH=$(jq -r '.branchName // empty' "$PRD_FILE" 2>/dev/null || echo "")
if [ -n "$CURRENT_BRANCH" ]; then
echo "$CURRENT_BRANCH" > "$LAST_BRANCH_FILE"
fi
fi

# Initialize progress file if it doesn't exist
# ------------------------------------------------------------
# Initialize progress file if needed
# ------------------------------------------------------------
if [ ! -f "$PROGRESS_FILE" ]; then
echo "# Ralph Progress Log" > "$PROGRESS_FILE"
echo "Started: $(date)" >> "$PROGRESS_FILE"
Expand All @@ -81,8 +91,12 @@ fi

echo "Starting Ralph - Tool: $TOOL - Max iterations: $MAX_ITERATIONS"

for i in $(seq 1 $MAX_ITERATIONS); do
# ------------------------------------------------------------
# Main agent loop
# ------------------------------------------------------------
for i in $(seq 1 "$MAX_ITERATIONS"); do
echo ""

echo "==============================================================="
echo " Ralph Iteration $i of $MAX_ITERATIONS ($TOOL)"
echo "==============================================================="
Expand All @@ -102,7 +116,7 @@ for i in $(seq 1 $MAX_ITERATIONS); do
echo "Completed at iteration $i of $MAX_ITERATIONS"
exit 0
fi

echo "Iteration $i complete. Continuing..."
sleep 2
done
Expand Down
57 changes: 57 additions & 0 deletions scripts/validate_prd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash
set -e

FILE=${1:-prd.json}

# Ensure PRD file exists
if [ ! -f "$FILE" ]; then
echo "✗ PRD file not found: $FILE"
exit 1
fi

# Ensure jq is available
if ! command -v jq >/dev/null 2>&1; then
echo "✗ jq is required but not installed"
exit 1
fi

# Fields that must exist on each user story
REQUIRED_FIELDS=("id" "title" "priority")
ERROR=0

echo "Validating PRD: $FILE"
echo "-------------------------"

# Ensure userStories exists and is an array
if ! jq -e '.userStories | type == "array"' "$FILE" >/dev/null; then
echo "✗ 'userStories' must be an array"
exit 1
fi

# Check for duplicate IDs
IDS=$(jq -r '.userStories[].id' "$FILE")
DUP_IDS=$(echo "$IDS" | sort | uniq -d)
if [ -n "$DUP_IDS" ]; then
echo "✗ Duplicate userStory IDs:"
echo "$DUP_IDS"
ERROR=1
fi

# Validate required fields exist (existence, not truthiness)
COUNT=$(jq '.userStories | length' "$FILE")
for ((i=0; i<COUNT; i++)); do
for FIELD in "${REQUIRED_FIELDS[@]}"; do
EXISTS=$(jq ".userStories[$i] | has(\"$FIELD\")" "$FILE")
if [ "$EXISTS" != "true" ]; then
echo "✗ Missing field '$FIELD' in userStory index $i"
ERROR=1
fi
done
done

if [ "$ERROR" -eq 0 ]; then
echo "✓ PRD is valid"
else
echo "✗ PRD validation failed"
exit 1
fi