Skip to content

feat(date): Add cross-platform date compatibility for macOS and Linux#9

Merged
frankbria merged 2 commits into
mainfrom
fix/cross-platform-date-compatibility
Dec 31, 2025
Merged

feat(date): Add cross-platform date compatibility for macOS and Linux#9
frankbria merged 2 commits into
mainfrom
fix/cross-platform-date-compatibility

Conversation

@frankbria
Copy link
Copy Markdown
Owner

@frankbria frankbria commented Dec 31, 2025

Summary

Adds cross-platform date compatibility to resolve GNU date vs BSD date differences between Linux and macOS systems. This fixes issues where Ralph would fail on macOS due to unsupported date command flags.

Problem

  • GNU date (Linux) uses -Iseconds for ISO 8601 formatting and -d for date arithmetic
  • BSD date (macOS) doesn't support these flags, causing Ralph to fail on macOS
  • 7 instances across 3 shell scripts were using GNU-specific date syntax

Solution

  • Created lib/date_utils.sh with cross-platform date utility functions
  • get_iso_timestamp() - Auto-detects OS and uses appropriate syntax for ISO 8601 timestamps
  • get_next_hour_time() - Auto-detects OS and uses appropriate syntax for date arithmetic
  • Updated all affected scripts to source and use the new utilities

Changes

  • New File: lib/date_utils.sh - Cross-platform date utility library
  • Modified: ralph_loop.sh - Updated 2 date operations (status timestamps)
  • Modified: lib/circuit_breaker.sh - Updated 4 date operations (state tracking)
  • Modified: lib/response_analyzer.sh - Updated 1 date operation (analysis timestamps)

Platform Support

  • Linux: Uses GNU date commands (date -Iseconds, date -d)
  • macOS: Uses BSD date commands (date -u +format, date -v)

Test Plan

Linux Testing (Completed)

  • Syntax validation on all modified scripts
  • Library sourcing integration tests
  • Date utility function output validation
  • JSON timestamp formatting verification

macOS Testing (Required)

  • Test get_iso_timestamp() returns valid ISO 8601 format
  • Test get_next_hour_time() returns valid time format (HH:MM:SS)
  • Run ralph_loop.sh and verify status.json timestamps
  • Verify circuit breaker state file timestamps
  • Verify response analyzer timestamps

Integration Testing

  • Run full Ralph loop cycle on macOS
  • Verify no "illegal option" or "invalid date" errors
  • Confirm JSON output is consistent across platforms
  • Test rate limiting countdown displays correctly

Manual Verification Commands

# Test date utilities directly
source lib/date_utils.sh
get_iso_timestamp  # Should output: YYYY-MM-DDTHH:MM:SS+00:00
get_next_hour_time # Should output: HH:MM:SS

# Test Ralph loop integration
ralph --status      # Check status.json formatting

Breaking Changes

None - This is a backward-compatible enhancement that maintains all existing functionality.

Notes

  • The implementation uses uname for OS detection
  • All date operations now go through the utility layer
  • The solution is self-contained in lib/date_utils.sh with no external dependencies

Summary by CodeRabbit

  • Refactor
    • Improved cross-platform date/time handling to produce consistent ISO‑style timestamps and next-reset times on GNU/Linux and BSD/macOS.
    • Updated emitted timestamps in logs and JSON outputs for uniform formatting across environments.

✏️ Tip: You can customize this high-level summary in your review settings.

Add cross-platform date utility library to handle differences between
GNU date (Linux) and BSD date (macOS). Fixes issues with:
- ISO 8601 timestamp formatting (-Iseconds flag)
- Date arithmetic operations (-d vs -v flags)

Changes:
- Created lib/date_utils.sh with get_iso_timestamp() and get_next_hour_time()
- Updated ralph_loop.sh to use date utilities (2 instances)
- Updated lib/circuit_breaker.sh to use date utilities (4 instances)
- Updated lib/response_analyzer.sh to use date utilities (1 instance)

All date operations now work consistently across both platforms without
modification. The utility automatically detects the OS and uses the
appropriate date command syntax.

Tested on Linux with GNU date - all syntax checks and integration tests pass.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 31, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

A new cross-platform date utilities library was added and three shell scripts were updated to source it and replace direct date invocations with the new helper functions for ISO timestamps and next-hour calculations.

Changes

Cohort / File(s) Summary
Date Utilities Library
lib/date_utils.sh
New file providing get_iso_timestamp(), get_next_hour_time(), and get_basic_timestamp() with OS detection (GNU vs BSD/macOS) and appropriate date command usage.
Circuit breaker / history timestamps
lib/circuit_breaker.sh
Now sources lib/date_utils.sh and replaces date -Iseconds calls with get_iso_timestamp() for JSON last_change and timestamp fields.
Response analyzer timestamps
lib/response_analyzer.sh
Now sources lib/date_utils.sh and replaces date -Iseconds with get_iso_timestamp() for emitted JSON and human-readable logs.
Main loop / status and reset time
ralph_loop.sh
Now sources lib/date_utils.sh; replaces date -Iseconds with get_iso_timestamp() and the date -d '+1 hour' next-reset calculation with get_next_hour_time().

Sequence Diagram(s)

(omitted — changes are focused on utility extraction and direct replacements; no new multi-component control flow introduced)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I nibbled timestamps, fixed their clatter,
Swapped brittle date calls for a cross-platform matter.
From Linux plains to macOS hill,
My ISO hops are tidy and still.
⏱️✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding cross-platform date compatibility. It directly matches the primary objective of the PR and is specific enough to convey the core purpose without being verbose.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d7db2c and 70279c0.

📒 Files selected for processing (1)
  • lib/date_utils.sh

Comment @coderabbitai help to get the list of available commands and usage tips.

@frankbria frankbria linked an issue Dec 31, 2025 that may be closed by this pull request
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
lib/date_utils.sh (2)

37-41: Document the unused function or consider removing it.

The get_basic_timestamp() function is not currently used by any of the modified scripts in this PR. Consider either documenting its intended future use or removing it to maintain a lean codebase.


7-8: Enhance function documentation to fully comply with coding guidelines.

Per coding guidelines, "All bash script functions must include comments documenting their purpose, parameters, and behavior." The current comments document purpose and return format but should explicitly note that these functions take no parameters.

🔎 Proposed documentation enhancement
 # Get current timestamp in ISO 8601 format with seconds precision
+# Parameters: None
 # Returns: YYYY-MM-DDTHH:MM:SS+00:00 format
 get_iso_timestamp() {

 # Get time component (HH:MM:SS) for one hour from now
+# Parameters: None
 # Returns: HH:MM:SS format
 get_next_hour_time() {

 # Get current timestamp in a basic format (fallback)
+# Parameters: None
 # Returns: YYYY-MM-DD HH:MM:SS format
 get_basic_timestamp() {

Based on coding guidelines: "All bash script functions must include comments documenting their purpose, parameters, and behavior"

Also applies to: 22-23, 37-38

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42b3a1e and 3d7db2c.

📒 Files selected for processing (4)
  • lib/circuit_breaker.sh
  • lib/date_utils.sh
  • lib/response_analyzer.sh
  • ralph_loop.sh
🧰 Additional context used
📓 Path-based instructions (3)
**/*.sh

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.sh: All bash script functions must include comments documenting their purpose, parameters, and behavior
Keep bash script comments current and remove outdated comments immediately when implementation changes

Files:

  • lib/date_utils.sh
  • lib/response_analyzer.sh
  • ralph_loop.sh
  • lib/circuit_breaker.sh
lib/response_analyzer.sh

📄 CodeRabbit inference engine (CLAUDE.md)

Use two-stage error filtering in error detection to eliminate JSON field false positives: Stage 1 filters field patterns like "is_error": false, Stage 2 detects actual errors via context (Error:, ERROR:, Exception, etc.)

Files:

  • lib/response_analyzer.sh
lib/circuit_breaker.sh

📄 CodeRabbit inference engine (CLAUDE.md)

Use literal fixed-string matching with grep -qF for multi-line error detection to avoid regex edge cases when detecting stuck loops with multiple simultaneous errors

Files:

  • lib/circuit_breaker.sh
🧠 Learnings (5)
📚 Learning: 2025-12-31T21:28:57.468Z
Learnt from: CR
Repo: frankbria/ralph-claude-code PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-31T21:28:57.468Z
Learning: Applies to lib/response_analyzer.sh : Use two-stage error filtering in error detection to eliminate JSON field false positives: Stage 1 filters field patterns like `"is_error": false`, Stage 2 detects actual errors via context (Error:, ERROR:, Exception, etc.)

Applied to files:

  • lib/response_analyzer.sh
📚 Learning: 2025-12-31T21:28:57.468Z
Learnt from: CR
Repo: frankbria/ralph-claude-code PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-31T21:28:57.468Z
Learning: Update CLAUDE.md when new commands, exit conditions, thresholds, or Ralph loop behaviors are introduced

Applied to files:

  • ralph_loop.sh
📚 Learning: 2025-12-31T21:28:57.468Z
Learnt from: CR
Repo: frankbria/ralph-claude-code PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-31T21:28:57.468Z
Learning: Test Ralph loop functionality with new features and verify installation process when applicable before marking features complete

Applied to files:

  • ralph_loop.sh
📚 Learning: 2025-12-31T21:28:57.468Z
Learnt from: CR
Repo: frankbria/ralph-claude-code PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-31T21:28:57.468Z
Learning: Files prefixed with `@` (e.g., `fix_plan.md`, `AGENT.md`) are Ralph-specific control files; hidden files (e.g., `.call_count`) track loop state; logs are timestamped in `logs/` directory

Applied to files:

  • ralph_loop.sh
📚 Learning: 2025-12-31T21:28:57.468Z
Learnt from: CR
Repo: frankbria/ralph-claude-code PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-31T21:28:57.468Z
Learning: Applies to lib/circuit_breaker.sh : Use literal fixed-string matching with `grep -qF` for multi-line error detection to avoid regex edge cases when detecting stuck loops with multiple simultaneous errors

Applied to files:

  • lib/circuit_breaker.sh
🧬 Code graph analysis (3)
lib/date_utils.sh (1)
tests/helpers/test_helper.bash (1)
  • date (194-202)
ralph_loop.sh (1)
lib/date_utils.sh (2)
  • get_iso_timestamp (8-20)
  • get_next_hour_time (24-35)
lib/circuit_breaker.sh (1)
lib/date_utils.sh (1)
  • get_iso_timestamp (8-20)
🔇 Additional comments (7)
lib/response_analyzer.sh (2)

5-6: LGTM!

The sourcing of date utilities is correctly implemented with proper path resolution using dirname "${BASH_SOURCE[0]}".


158-158: LGTM!

The replacement of date -Iseconds with get_iso_timestamp() correctly delegates timestamp generation to the cross-platform utility.

lib/circuit_breaker.sh (2)

6-7: LGTM!

The sourcing of date utilities is correctly implemented with proper path resolution.


42-42: LGTM!

All four timestamp generations have been correctly updated to use get_iso_timestamp() instead of direct date -Iseconds invocations, ensuring cross-platform compatibility across state initialization, loop result recording, transition logging, and circuit breaker reset operations.

Also applies to: 170-170, 202-202, 278-278

ralph_loop.sh (2)

10-10: LGTM!

The sourcing of date utilities is correctly placed before other library components that may depend on it.


168-168: LGTM!

Both timestamp replacements are correct:

  • Line 168: get_iso_timestamp() provides ISO 8601 format for status tracking
  • Line 175: get_next_hour_time() handles date arithmetic for the next reset time

Also applies to: 175-175

lib/date_utils.sh (1)

22-35: LGTM!

The get_next_hour_time() function correctly implements cross-platform date arithmetic using BSD's -v flag for macOS and GNU's -d flag for Linux. Both use local time consistently.

Comment thread lib/date_utils.sh
Add -u flag to GNU date command in get_iso_timestamp() to match
the macOS implementation and function documentation. Both platforms
now consistently return UTC timestamps in YYYY-MM-DDTHH:MM:SS+00:00
format.

Before: date -Iseconds (returned local time on Linux)
After:  date -u -Iseconds (returns UTC on Linux)
@frankbria frankbria merged commit 6c647ef into main Dec 31, 2025
2 of 3 checks passed
@frankbria frankbria deleted the fix/cross-platform-date-compatibility branch December 31, 2025 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: date: illegal option -- d on macOS

1 participant