Skip to content

Commit cfcdab3

Browse files
duyetclaudeduyetbot
committed
fix(ralph-wiggum): cross-platform compatibility for macOS/Linux/WSL
- Add _hash() function supporting md5sum (Linux), md5 (macOS), cksum (fallback) - Replace bash arrays with space-separated strings in api_limit_handler.sh - Change set -euo to set -eo in all lib scripts for compatibility - Update calculate_file_hash() and calculate_output_hash() to use _hash() - Add iteration-log.md to track progress Tested: All 8 scripts pass syntax check, all 11 bats tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Co-Authored-By: duyetbot <duyetbot@users.noreply.github.com>
1 parent 3531c26 commit cfcdab3

5 files changed

Lines changed: 108 additions & 13 deletions

File tree

.claude/iteration-log.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Iteration Log
2+
3+
## Iteration 2 (Current)
4+
5+
### What Was Done
6+
1. **Cross-Platform Compatibility Fixes**
7+
- Added `_hash()` function for cross-platform hashing (md5sum/md5/cksum)
8+
- Fixed `circuit_breaker.sh` to use portable hash function
9+
- Replaced bash arrays with space-separated strings in `api_limit_handler.sh`
10+
- Changed all `set -euo` to `set -eo` to avoid nounset issues
11+
12+
2. **Scripts Fixed**
13+
- `circuit_breaker.sh`: Added `_hash()`, fixed `calculate_file_hash()`, `calculate_output_hash()`
14+
- `api_limit_handler.sh`: Replaced array with string, fixed `detect_rate_limit()`
15+
- `task_manager.sh`: Changed to `set -eo`
16+
17+
3. **Verification**
18+
- All 8 scripts pass `bash -n` syntax check
19+
- All 11 bats tests passing
20+
21+
### What Was Found
22+
- All scripts now use portable constructs
23+
- Other plugins still need documentation review
24+
25+
### What Needs To Be Done Next
26+
1. Review and update frontend-design plugin docs
27+
2. Review and update interview plugin docs
28+
3. Review and update team-agents plugin docs
29+
4. Review and update commit-commands plugin docs
30+
5. Add more bats tests for hash function and cross-platform behavior
31+
32+
---
33+
34+
## Iteration 1
35+
36+
### What Was Done
37+
1. **Documentation Updates (ralph-wiggum)**
38+
- Updated Architecture section with actual file structure
39+
- Fixed file paths from `/tmp/ralph_*` to `.claude/ralph-*`
40+
- Added comprehensive Troubleshooting section
41+
- Expanded Prompt Guidelines with practical examples
42+
- Added `/status` command to main README
43+
- Fixed `help.md` monitoring paths
44+
45+
2. **Bug Fixes**
46+
- Fixed `response_analyzer.sh` "unbound variable" error
47+
- Replaced `declare -A` associative arrays with portable string format
48+
- Changed `set -euo` to `set -eo` for compatibility
49+
50+
3. **CI/CD**
51+
- Added `.github/workflows/bash-tests.yml`
52+
- ShellCheck, syntax check, bash version compatibility (4.4-5.2)
53+
- bats-core unit tests (11 tests passing)
54+
55+
### What Was Found
56+
- Scripts use macOS-specific commands (`md5` instead of `md5sum`)
57+
- Need to verify cross-platform compatibility (macOS, Linux, WSL)
58+
- Other plugins (frontend-design, interview, team-agents, etc.) need doc review

.claude/ralph-loop.local.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
active: true
3+
iteration: 2
4+
max_iterations: 0
5+
completion_promise: null
6+
circuit_breaker: true
7+
smart_exit: true
8+
rate_limit_handler: true
9+
started_at: "2025-12-30T03:49:41Z"
10+
---
11+
12+
update docs for all plugins until see it perfect
13+
Make sure scripts are working on both MacOS and Linux and Windows Linux Subsystem
14+
Detect any bugs as needed
15+
Update this file for each iteration with what was done, what was found, and what needs to be done next, until completion

ralph-wiggum/lib/api_limit_handler.sh

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@
33
# API Limit Handler for Ralph Wiggum
44
# Handles Claude's 5-hour usage limits and rate limiting
55

6-
set -euo pipefail
6+
set -eo pipefail
77

88
LIMIT_STATE_FILE="${RALPH_STATE_DIR:-.claude}/ralph-limits.json"
99
DEFAULT_WAIT_SECONDS=${RALPH_WAIT_SECONDS:-3600}
1010

11-
RATE_LIMIT_PATTERNS=(
12-
"rate limit" "rate_limit" "too many requests" "429" "quota exceeded"
13-
"usage limit" "daily limit" "hourly limit" "5-hour" "5 hour"
14-
"exceeded.*limit" "limit.*exceeded" "overloaded" "capacity"
15-
)
11+
# Rate limit patterns as space-separated string (portable across bash versions)
12+
RATE_LIMIT_PATTERNS="rate_limit too_many_requests 429 quota_exceeded usage_limit daily_limit hourly_limit 5-hour 5_hour exceeded_limit limit_exceeded overloaded capacity"
1613

1714
init_limit_handler() {
1815
[[ -f "$LIMIT_STATE_FILE" ]] && return
@@ -34,8 +31,10 @@ detect_rate_limit() {
3431
local output="$1"
3532
local output_lower=$(echo "$output" | tr '[:upper:]' '[:lower:]')
3633

37-
for pattern in "${RATE_LIMIT_PATTERNS[@]}"; do
38-
echo "$output_lower" | grep -qiE "$pattern" && { echo "true"; return 0; }
34+
for pattern in $RATE_LIMIT_PATTERNS; do
35+
# Convert underscores to spaces/regex for matching
36+
local search_term="${pattern//_/[_ ]}"
37+
echo "$output_lower" | grep -qiE "$search_term" && { echo "true"; return 0; }
3938
done
4039
echo "false"
4140
}

ralph-wiggum/lib/circuit_breaker.sh

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,26 @@
33
# Circuit Breaker for Ralph Wiggum
44
# Prevents runaway loops by detecting stagnation, errors, and duplicate outputs
55

6-
set -euo pipefail
6+
set -eo pipefail
77

88
CIRCUIT_STATE_FILE="${RALPH_STATE_DIR:-.claude}/ralph-circuit.json"
99
MAX_NO_PROGRESS_LOOPS=${RALPH_MAX_NO_PROGRESS:-3}
1010
MAX_CONSECUTIVE_ERRORS=${RALPH_MAX_ERRORS:-5}
1111
MAX_IDENTICAL_OUTPUTS=${RALPH_MAX_IDENTICAL:-3}
1212
HALF_OPEN_THRESHOLD=${RALPH_HALF_OPEN_THRESHOLD:-2}
1313

14+
# Cross-platform hash function (works on macOS, Linux, WSL)
15+
_hash() {
16+
if command -v md5sum &>/dev/null; then
17+
md5sum | cut -d' ' -f1
18+
elif command -v md5 &>/dev/null; then
19+
md5 -q
20+
else
21+
# Fallback: use cksum if neither available
22+
cksum | cut -d' ' -f1
23+
fi
24+
}
25+
1426
init_circuit_breaker() {
1527
[[ -f "$CIRCUIT_STATE_FILE" ]] && return
1628
cat > "$CIRCUIT_STATE_FILE" <<EOF
@@ -42,16 +54,26 @@ can_execute() {
4254

4355
calculate_file_hash() {
4456
local project_dir="${1:-.}"
45-
find "$project_dir" -type f \
57+
# Find all relevant files and hash their contents
58+
local file_list
59+
file_list=$(find "$project_dir" -type f \
4660
\( -name "*.js" -o -name "*.ts" -o -name "*.py" -o -name "*.go" \
4761
-o -name "*.rs" -o -name "*.java" -o -name "*.sh" -o -name "*.md" \
4862
-o -name "*.json" -o -name "*.yaml" -o -name "*.yml" \) \
4963
! -path "*node_modules*" ! -path "*/.git/*" ! -path "*/.claude/*" \
50-
-exec md5 -q {} \; 2>/dev/null | sort | md5 -q 2>/dev/null || echo "no_files"
64+
2>/dev/null | sort)
65+
66+
if [[ -z "$file_list" ]]; then
67+
echo "no_files"
68+
return
69+
fi
70+
71+
# Hash file contents (cross-platform)
72+
echo "$file_list" | xargs cat 2>/dev/null | _hash || echo "no_files"
5173
}
5274

5375
calculate_output_hash() {
54-
echo -n "$1" | md5 -q 2>/dev/null || echo "no_output"
76+
echo -n "$1" | _hash 2>/dev/null || echo "no_output"
5577
}
5678

5779
record_loop_result() {
@@ -204,5 +226,6 @@ cleanup_circuit_breaker() {
204226
rm -f "$CIRCUIT_STATE_FILE"
205227
}
206228

229+
export -f _hash calculate_file_hash calculate_output_hash
207230
export -f init_circuit_breaker get_circuit_state can_execute record_loop_result
208231
export -f get_halt_reason show_circuit_status reset_circuit_breaker cleanup_circuit_breaker

ralph-wiggum/lib/task_manager.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Task Manager for Ralph Wiggum
44
# Hierarchical task tracking with progress monitoring
55

6-
set -euo pipefail
6+
set -eo pipefail
77

88
TASK_STATE_FILE="${RALPH_STATE_DIR:-.claude}/ralph-tasks.json"
99
TASK_PLAN_FILE="${RALPH_STATE_DIR:-.claude}/ralph-plan.md"

0 commit comments

Comments
 (0)