Merge pull request #9 from frankbria/fix/cross-platform-date-compatibility

feat(date): Add cross-platform date compatibility for macOS and Linux
This commit is contained in:
Frank Bria 2025-12-31 16:49:01 -07:00 committed by GitHub
commit 6c647ef433
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 55 additions and 7 deletions

View file

@ -3,6 +3,9 @@
# Prevents runaway token consumption by detecting stagnation
# Based on Michael Nygard's "Release It!" pattern
# Source date utilities for cross-platform compatibility
source "$(dirname "${BASH_SOURCE[0]}")/date_utils.sh"
# Circuit Breaker States
CB_STATE_CLOSED="CLOSED" # Normal operation, progress detected
CB_STATE_HALF_OPEN="HALF_OPEN" # Monitoring mode, checking for recovery
@ -36,7 +39,7 @@ init_circuit_breaker() {
cat > "$CB_STATE_FILE" << EOF
{
"state": "$CB_STATE_CLOSED",
"last_change": "$(date -Iseconds)",
"last_change": "$(get_iso_timestamp)",
"consecutive_no_progress": 0,
"consecutive_same_error": 0,
"last_progress_loop": 0,
@ -164,7 +167,7 @@ record_loop_result() {
cat > "$CB_STATE_FILE" << EOF
{
"state": "$new_state",
"last_change": "$(date -Iseconds)",
"last_change": "$(get_iso_timestamp)",
"consecutive_no_progress": $consecutive_no_progress,
"consecutive_same_error": $consecutive_same_error,
"last_progress_loop": $last_progress_loop,
@ -196,7 +199,7 @@ log_circuit_transition() {
local history=$(cat "$CB_HISTORY_FILE")
local transition="{
\"timestamp\": \"$(date -Iseconds)\",
\"timestamp\": \"$(get_iso_timestamp)\",
\"loop\": $loop_number,
\"from_state\": \"$from_state\",
\"to_state\": \"$to_state\",
@ -272,7 +275,7 @@ reset_circuit_breaker() {
cat > "$CB_STATE_FILE" << EOF
{
"state": "$CB_STATE_CLOSED",
"last_change": "$(date -Iseconds)",
"last_change": "$(get_iso_timestamp)",
"consecutive_no_progress": 0,
"consecutive_same_error": 0,
"last_progress_loop": 0,

41
lib/date_utils.sh Normal file
View file

@ -0,0 +1,41 @@
#!/usr/bin/env bash
# date_utils.sh - Cross-platform date utility functions
# Provides consistent date formatting and arithmetic across GNU (Linux) and BSD (macOS) systems
# Get current timestamp in ISO 8601 format with seconds precision
# Returns: YYYY-MM-DDTHH:MM:SS+00:00 format
get_iso_timestamp() {
local os_type
os_type=$(uname)
if [[ "$os_type" == "Darwin" ]]; then
# macOS (BSD date)
# Use manual formatting and add colon to timezone offset
date -u +"%Y-%m-%dT%H:%M:%S%z" | sed 's/\(..\)$/:\1/'
else
# Linux (GNU date) - use -u flag for UTC
date -u -Iseconds
fi
}
# Get time component (HH:MM:SS) for one hour from now
# Returns: HH:MM:SS format
get_next_hour_time() {
local os_type
os_type=$(uname)
if [[ "$os_type" == "Darwin" ]]; then
# macOS (BSD date) - use -v flag for date arithmetic
date -v+1H '+%H:%M:%S'
else
# Linux (GNU date) - use -d flag for date arithmetic
date -d '+1 hour' '+%H:%M:%S'
fi
}
# Get current timestamp in a basic format (fallback)
# Returns: YYYY-MM-DD HH:MM:SS format
get_basic_timestamp() {
date '+%Y-%m-%d %H:%M:%S'
}

View file

@ -2,6 +2,9 @@
# Response Analyzer Component for Ralph
# Analyzes Claude Code output to detect completion signals, test-only loops, and progress
# Source date utilities for cross-platform compatibility
source "$(dirname "${BASH_SOURCE[0]}")/date_utils.sh"
# Response Analysis Functions
# Based on expert recommendations from Martin Fowler, Michael Nygard, Sam Newman
@ -152,7 +155,7 @@ analyze_response() {
cat > "$analysis_result_file" << EOF
{
"loop_number": $loop_number,
"timestamp": "$(date -Iseconds)",
"timestamp": "$(get_iso_timestamp)",
"output_file": "$output_file",
"analysis": {
"has_completion_signal": $has_completion_signal,

View file

@ -7,6 +7,7 @@ set -e # Exit on any error
# Source library components
SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
source "$SCRIPT_DIR/lib/date_utils.sh"
source "$SCRIPT_DIR/lib/response_analyzer.sh"
source "$SCRIPT_DIR/lib/circuit_breaker.sh"
@ -164,14 +165,14 @@ update_status() {
cat > "$STATUS_FILE" << STATUSEOF
{
"timestamp": "$(date -Iseconds)",
"timestamp": "$(get_iso_timestamp)",
"loop_count": $loop_count,
"calls_made_this_hour": $calls_made,
"max_calls_per_hour": $MAX_CALLS_PER_HOUR,
"last_action": "$last_action",
"status": "$status",
"exit_reason": "$exit_reason",
"next_reset": "$(date -d '+1 hour' -Iseconds | cut -d'T' -f2 | cut -d'+' -f1)"
"next_reset": "$(get_next_hour_time)"
}
STATUSEOF
}