Commit graph

157 commits

Author SHA1 Message Date
Test User
42f5df6299 fix: prevent session hijacking and improve reliability
- Use --resume <session_id> instead of --continue to avoid hijacking
  active Claude Code sessions in the same directory (Issue #151)
- Write log_status output to stderr to prevent log messages from
  interfering with function return values

The --continue flag resumes "most recent session in current directory"
which can inadvertently take over an unrelated Claude Code session.
Now Ralph only resumes its own sessions by explicit ID.

Fixes #151
Credit: @dionny (PR #153)
2026-02-02 09:47:57 -07:00
Test User
43bba1beb7 fix(analyzer): respect explicit EXIT_SIGNAL:false with STATUS:COMPLETE
When Claude outputs STATUS: COMPLETE with EXIT_SIGNAL: false, it means
"this task is complete, but there are more tasks to do". Previously,
STATUS: COMPLETE incorrectly overrode EXIT_SIGNAL, causing premature exit.

The fix:
- Track whether EXIT_SIGNAL was explicitly provided (vs inferred)
- Only use STATUS: COMPLETE as fallback when no EXIT_SIGNAL was specified
- Explicit EXIT_SIGNAL: false is now respected (continues working)

Fixes #146
Credit: @linuxkd (PR #147)
2026-02-02 09:45:01 -07:00
Test User
da84dbc32f feat(loop): add support for non-zero first-window tmux configs
Fixes tmux targeting for users with custom base-index configuration.

Changes:
- Add get_tmux_base_index() to detect tmux window base-index setting
- Replace hardcoded :0 window references with dynamic ${base_win}
- Handles configurations like 'set -g base-index 1'

Credit: @jimrubenstein (PR #145)
2026-02-02 09:42:17 -07:00
Test User
3ed0a9d9ff fix(date): improve cross-platform date command compatibility
Fixes date command errors on macOS with Homebrew GNU coreutils:
- 'date: invalid option -- v' when GNU date runs BSD syntax
- 'syntax error in expression' when stat returns filesystem metadata

Changes:
- Replace uname-based detection with capability detection (try/fallback)
- Try GNU commands first, fall back to BSD, then ultimate fallbacks
- Add date -r fallback for file mtime (most portable)

This handles mixed environments where uname returns "Darwin" but
GNU coreutils are in PATH from Homebrew.

Credit: @farce1 (PR #119)
2026-02-02 09:39:39 -07:00
Test User
c05499c176 feat(circuit-breaker): allow configuring thresholds via environment variables
Makes circuit breaker thresholds configurable via environment variables
while maintaining backward compatibility with default values.

Usage:
  CB_NO_PROGRESS_THRESHOLD=10 ralph --monitor
  CB_SAME_ERROR_THRESHOLD=8 CB_OUTPUT_DECLINE_THRESHOLD=80 ralph

Configurable thresholds:
- CB_NO_PROGRESS_THRESHOLD (default: 3)
- CB_SAME_ERROR_THRESHOLD (default: 5)
- CB_OUTPUT_DECLINE_THRESHOLD (default: 70)
- CB_PERMISSION_DENIAL_THRESHOLD (default: 2)

Fixes #99
Credit: @zerone0x (PR #111)
2026-02-02 09:36:48 -07:00
Test User
fe94cbd02b fix(import): add --print flag to prevent ralph-import hanging
Without --print, Claude CLI starts an interactive session that hangs
when stdin comes from a file/pipe. This caused ralph-import to hang
indefinitely when converting PRDs.

Changes:
- Add --print flag for non-interactive (piped) input mode
- Add --strict-mcp-config to skip loading user MCP servers (faster startup)

Credit: @merlinrabens (PR #103)
2026-02-02 09:34:38 -07:00
Test User
5f3a1226b7 fix(import): handle absolute file paths in ralph-import
Previously, ralph-import would prepend '../' to the source file path
after cd'ing into the project directory. This breaks when an absolute
path is provided (e.g., /Users/foo/file.md becomes ..//Users/foo/file.md).

Now checks if the path is absolute (starts with /) before prepending '../'.

Credit: @GiladSchneider (PR #92)
2026-02-02 09:32:17 -07:00
Dawen Ren
48ba86a2de
fix: setup.sh and install.sh improvements (#155)
- setup.sh: Skip git init if .git already exists (prevents errors in existing repos)
- install.sh: Copy setup.sh directly instead of hardcoding a simplified version
  This ensures global installation uses the same setup logic as local,
  including .ralphrc generation via enable_core.sh

Co-authored-by: dawenrenhub <darwinren321@gmail.com>
2026-02-02 09:00:11 -07:00
Test User
627ad7d9a5 fix: extract denied commands from correct JSON path (Issue #143)
The permission_denials array from Claude CLI has commands nested under
tool_input.command, not directly as .command:

Before: jq '[.permission_denials[].command]'
After:  jq '[.permission_denials[].tool_input.command]'

This fixes the "Permission denied for N command(s)" message to actually
display the denied commands instead of showing empty/unknown.

Also updated test fixture to match real Claude CLI output structure.
2026-02-01 13:43:47 -07:00
Test User
2e6026aced docs: update version to v0.11.3 and test count to 452
- Bump version from v0.11.2 to v0.11.3
- Update test count from 440 to 452 across all badges and references
- Add v0.11.3 release notes for live streaming output (#125) and beads fix (#150)
- Document --live flag for real-time Claude Code visibility
- Add Live Streaming Output configuration section
2026-02-01 13:28:52 -07:00
Dawen Ren
66947e7005
fix: update ralph_import.sh (#148)
Fix ralph_import.sh CLI detection:
- Replace npx @anthropic/claude-code check with CLAUDE_CODE_CMD variable
- Quote CLAUDE_CODE_CMD to prevent shell expansion issues
- Add jq dependency check with installation guidance
2026-02-01 13:28:26 -07:00
Dionny Santiago
02dbb078d7
fix: beads task import uses correct bd list arguments (#150)
Apply 3 CodeRabbit review suggestions:
- Rename variables to camelCase (filter_status → filterStatus, bd_args → bdArgs)
- Fix fallback path to respect status filter instead of plain bd list
- Add jq select guard for missing id/title fields with error handling
2026-02-01 12:53:01 -07:00
André Théo LAURET
9aa2fefb95
feat: Add live streaming output mode with real-time Claude Code visibility (#125)
* feat: Add live streaming output mode with real-time Claude Code visibility

New features:
- Add --live flag for real-time streaming output using stream-json + jq
- Display tool usage with visual indicators ( [Read],  [Bash], etc.)
- Add line breaks between messages for better readability
- Integrate live mode automatically in --monitor tmux layout
- Add IS_SANDBOX=1 and CLAUDE_CODE_ENABLE_DANGEROUS_PERMISSIONS_IN_SANDBOX=1
  environment variables to allow --dangerously-skip-permissions with root
- Remove DEBUG log messages for cleaner output

The live streaming uses Claude Code's --output-format stream-json with jq
to extract and display text in real-time, allowing users to watch Claude
work as it happens.

tmux --monitor layout now shows:
- Left pane: Ralph loop with live streaming
- Right-top pane: tail -f on live.log
- Right-bottom pane: Status monitor

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(live): use CLAUDE_CMD_ARGS for live mode, remove sandbox exports

Live mode now properly uses build_claude_command() to preserve:
- --allowedTools (tool permissions from .ralphrc)
- --append-system-prompt (loop context)
- --continue (session continuity for save_claude_session())
- -p (prompt content)

Changes:
- Remove unconditional CLAUDE_CODE_ENABLE_DANGEROUS_PERMISSIONS_IN_SANDBOX
  and IS_SANDBOX exports (tool restrictions via --allowedTools is sufficient)
- Live mode builds LIVE_CMD_ARGS from CLAUDE_CMD_ARGS, replacing
  --output-format json with stream-json
- Add --verbose and --include-partial-messages for streaming
- Remove --dangerously-skip-permissions from legacy fallback mode
- Preserves session ID extraction for save_claude_session()

* fix(live): address critical issues in live mode implementation

Issue 1 - Session Continuity:
- Extract session_id from stream-json output after streaming completes
- Find the "result" type message and convert to standard JSON format
- Save to separate session file for save_claude_session() to parse

Issue 2 - Security Model:
- Remove --dangerously-skip-permissions from build_claude_command()
- Tool permissions now properly controlled via --allowedTools
- Preserves permission denial circuit breaker (Issue #101)

Issue 3 - Dependency Checks:
- Add checks for jq and stdbuf before enabling live mode
- Fall back to background mode if dependencies missing

Issue 4 - Pipeline Error Handling:
- Use set -o pipefail to capture all pipeline exit codes
- Capture PIPESTATUS array for each pipeline stage
- Warn on jq parsing issues without failing the loop
- Primary exit code from Claude command preserved

* fix(live): add timeout protection and improve session handling robustness

Issue 1 - Missing Timeout Protection:
- Add portable_timeout to live mode pipeline for consistent timeout behavior
- Prevents indefinite hangs matching background mode behavior

Issue 2 - Session Continuity Robustness:
- Use flexible regex [[:space:]]* to match various JSON formatting styles
- Preserve full stream output in _stream.log BEFORE modifying output_file
- Validate extracted JSON with jq -e before using it
- Restore stream output if validation fails

Issue 3 - Pipeline Error Handling:
- Check pipe_status[1] (first tee) for write failures
- Warn if output file write fails (could break session/logging)
- All four pipeline stages now monitored

---------

Co-authored-by: André Théo LAURET <andrelauret@icloud.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Test User <test@example.com>
2026-01-30 20:28:09 -07:00
Test User
f558c14b24 fix(ci): add explicit github_token for pull_request_target
The OIDC token exchange fails with pull_request_target events.
Provide explicit github_token to fix authentication.
Also upgrade to pull-requests: write for posting comments.
2026-01-30 13:11:31 -07:00
Test User
b4042da156 fix(ci): revert opencode-review to pull_request trigger
The OpenCode action doesn't support pull_request_target event.
Revert to pull_request so it works for repo branch PRs.
Fork PRs will be reviewed by claude-code-review.yml instead.
2026-01-30 13:00:55 -07:00
Test User
a024830127 fix(ci): use pull_request_target for fork PR reviews
Switch both review workflows from pull_request to pull_request_target
so they run with base repo permissions and can access secrets when
reviewing fork PRs.

Changes:
- claude-code-review.yml: pull_request → pull_request_target
- opencode-review.yml: pull_request → pull_request_target
- Both now explicitly checkout PR head commit for review
- Added security comments explaining the approach

This allows the workflows to run successfully after maintainer approval
for external contributor PRs.
2026-01-30 08:09:49 -07:00
Frank Bria
328294847d
feat(exit): detect permission denials and halt loop (Issue #101) (#142)
When Claude Code is denied permission to execute commands (e.g., npm install),
Ralph now detects this from the permission_denials array in the JSON output
and halts the loop immediately with clear guidance for the user.

Changes:
- Add permission denial detection to parse_json_response() in response_analyzer.sh
  - Extract permission_denials array from Claude Code JSON output
  - Track has_permission_denials, permission_denial_count, denied_commands
- Add analyze_response() support for permission denial fields
- Add permission denial exit condition to should_exit_gracefully() in ralph_loop.sh
  - Permission denial takes highest priority among exit conditions
  - Display helpful guidance for updating ALLOWED_TOOLS in .ralphrc
- Update circuit breaker with CB_PERMISSION_DENIAL_THRESHOLD=2
  - Track consecutive_permission_denials in state file
  - Open circuit after 2 consecutive loops with permission denials
- Add 11 new TDD tests (6 in test_json_parsing.bats, 5 in test_exit_detection.bats)
- Update documentation in CLAUDE.md and README.md

Test count: 452 (up from 452 - added 11 new tests)

Fixes #101

Co-authored-by: Test User <test@example.com>
2026-01-29 23:17:16 -07:00
gwicho38
5cad271eac
fix: Recognize STATUS: COMPLETE as progress in circuit breaker (#140)
* fix: Recognize STATUS: COMPLETE as progress in circuit breaker

The circuit breaker was only detecting progress through git diff changes.
When Claude completed work and committed it, subsequent loops showed 0
uncommitted changes, causing the circuit breaker to trip after 3 loops.

This fix adds multiple progress detection sources:
1. Git diff changes (existing)
2. has_completion_signal from response analysis (STATUS: COMPLETE)
3. files_modified reported by Claude in RALPH_STATUS block

This ensures that completed work is recognized as progress even when
all changes have been committed to git.

Fixes issue where circuit breaker would repeatedly trip on projects
where Claude finishes tasks and commits them immediately.

* Update lib/circuit_breaker.sh

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: Frank Bria <frank.bria@proton.me>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-01-29 22:34:41 -07:00
Test User
dff2d358f6 docs: add user guide and example projects (#139)
New users were confused about which files they write vs. which Ralph
manages, and how PROMPT.md, specs/, and fix_plan.md relate to each other.

Added:
- docs/user-guide/ with quick start tutorial, file reference, and
  requirements writing guide
- examples/simple-cli-tool/ showing minimal Ralph configuration
- examples/rest-api/ demonstrating when to use specs/
- README section explaining Ralph files and their relationships

Also documents specs/stdlib/ purpose for reusable patterns.
2026-01-29 13:51:10 -07:00
Frank Bria
dbb27d89e9
fix(setup): create .ralphrc with consistent tool permissions (#137)
* fix(setup): create .ralphrc with consistent tool permissions (#136)

- Update default ALLOWED_TOOLS in ralph_loop.sh to include Edit,
  Bash(npm *), and Bash(pytest) for test execution capability
- Make setup.sh generate .ralphrc file using same permissions as
  ralph-enable, ensuring consistency between initialization paths
- Add 8 new TDD tests for .ralphrc creation and ALLOWED_TOOLS defaults
- Update documentation in README.md and CLAUDE.md

This fixes the mismatch where PROMPT.md instructs the model to run
tests, but the default permissions didn't allow it. Now both
ralph-setup and ralph-enable create projects with identical tool
permissions.

Test count: 440 (up from 424)

* fix: address PR review feedback

- Update version badges from v0.10.1 to v0.11.2 (README.md)
- Update test count badges from 310 to 440 (README.md, CLAUDE.md)
- Fix .ralphrc generator label: use sed to replace "ralph enable"
  with "ralph-setup" when using generate_ralphrc() from library
- Add v0.11.2 changelog entry to CLAUDE.md

* docs(readme): comprehensive update for v0.11.2

- Reorganize Recent Improvements with v0.11.x versions prominent
- Add ralph-enable wizard section with full documentation
- Add .ralphrc configuration section with example
- Update Quick Start to show ralph-enable as Option A (recommended)
- Update test counts to 440 across 15 files
- Collapse v0.9.x versions into expandable details section
- Add new features to What's Working Now section
- Link to issue #138 for automated badge updates
- Update Command Reference with new commands

---------

Co-authored-by: Test User <test@example.com>
2026-01-28 21:10:02 -07:00
Test User
33739e0fb2 Merge PR #126: fix(monitor): forward all CLI parameters to inner ralph loop
Cherry-pick of #126 rebased onto current main to pass CI.
Original work by @zerone0x. Fixes #120.

Co-Authored-By: zerone0x <hi@trine.dev>
Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-28 15:23:59 -07:00
zerone0x
83672d3a19 fix(monitor): forward all CLI parameters to inner ralph loop (#120)
When using --monitor flag, the tmux session now correctly forwards all
CLI parameters to the inner ralph_loop.sh execution instead of only
--calls and --prompt.

Added forwarding for:
- --output-format (json/text)
- --verbose
- --timeout
- --allowed-tools
- --no-continue
- --session-expiry

Added 8 new tests for parameter forwarding validation.
Test count: 329 (up from 321)

Fixes #120

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-28 15:20:01 -07:00
Frank Bria
0bd260df68
ci(workflow): add concurrency blocks to prevent duplicate runs (#135)
Add concurrency control to all review workflows:
- opencode-review.yml: Cancel in-progress for same PR
- claude-code-review.yml: Cancel in-progress for same PR
- claude.yml: Cancel in-progress for same issue/PR

This prevents duplicate reviews when PRs are updated rapidly
or multiple comments are posted in quick succession.

Co-authored-by: Test User <test@example.com>
2026-01-28 10:22:45 -07:00
Frank Bria
7df4750f22
fix(test): ensure RESPONSE_ANALYSIS_FILE is set before use in test 199 (#133)
Move variable exports before first use in the #91 regression test to
prevent "No such file or directory" failures in CI environments where
setup() state may not persist.

Co-authored-by: Test User <test@example.com>
2026-01-27 09:32:47 -07:00
Frank Bria
f6fde6780b
fix(exit-detection): use explicit EXIT_SIGNAL instead of confidence threshold (#132)
Replace confidence-based heuristic in update_exit_signals() with explicit
EXIT_SIGNAL checking. JSON mode always has confidence >= 70 due to
deterministic scoring, causing completion_indicators to fill after 5 loops
and triggering premature exits even when Claude sets EXIT_SIGNAL: false.

Changes:
- lib/response_analyzer.sh: Check exit_signal == "true" instead of
  confidence >= 60 when updating completion_indicators array
- ralph_loop.sh: Update safety circuit breaker comment to reflect that
  completion_indicators now only accumulates on EXIT_SIGNAL=true
- tests/unit/test_exit_detection.bats: Add 4 TDD tests (32-35) validating
  the fix for update_exit_signals() behavior
- CLAUDE.md: Document fix as v0.11.1, update test counts (420 → 424)

Test count: 424 passing (100% pass rate)

Co-authored-by: Test User <test@example.com>
2026-01-26 16:41:05 -07:00
Frank Bria
c7e7a1c6a3
refactor(naming): remove @ prefix from on-disk filenames (#131)
* refactor(naming): remove @ prefix from on-disk filenames

BREAKING CHANGE: Renames @fix_plan.md → fix_plan.md and @AGENT.md → AGENT.md

This change improves POSIX compliance and compatibility with command-line tools.
The @ prefix was originally used to avoid naming conflicts, but with the .ralph/
folder structure introduced in v0.10.0, this convention is no longer necessary.

Changes:
- Update all scripts to use new naming (fix_plan.md, AGENT.md)
- Update migration script to handle both old and new naming conventions
- Update templates to use new naming
- Update all documentation references
- Update all 420 tests to expect new naming (TDD approach)

Migration:
- Existing projects with @-prefixed files will be automatically renamed
  when running ralph-migrate
- Projects already using the new naming will continue to work unchanged

* docs(claude): update file naming conventions section

* fix(migrate): prevent orphaned @-prefixed files during migration

When both root/@fix_plan.md and .ralph/@fix_plan.md exist, the root file
now takes priority and the .ralph/@fix_plan.md is removed (backup exists).
This prevents orphaned legacy files after migration.

---------

Co-authored-by: Test User <test@example.com>
2026-01-26 15:40:27 -07:00
Frank Bria
05c57207f3
fix(wizard): redirect prompts to stderr for clean command substitution (#130)
When wizard prompt functions (prompt_text, prompt_number, select_option,
select_with_default) were used with command substitution, ANSI-colored
prompts were captured along with user responses, corrupting .ralphrc
values like: PROJECT_NAME="[0;36mProject name[0m [value]: value"

Fix:
- Redirect all display output (colored prompts, validation messages) to
  stderr using >&2, matching the pattern already used by select_multiple()
- Keep only the actual response/result on stdout for command substitution

Changes:
- lib/wizard_utils.sh: Add >&2 to prompt_text (lines 84-87),
  prompt_number (lines 118-121, 131-151), confirm (lines 44, 60),
  select_option (lines 190-215), select_with_default (lines 330-364)
- tests/unit/test_wizard_utils.bats: Add 20 new tests for stdout/stderr
  separation and clean command substitution results
- CLAUDE.md: Update test count to 420

Test count: 420 (up from 396)

Co-authored-by: Test User <test@example.com>
2026-01-26 14:47:06 -07:00
Frank Bria
910f794fcc
feat(enable): add ralph-enable wizard for existing projects (v0.11.0) (#124)
* feat(enable): add ralph-enable wizard for existing projects (v0.11.0)

Add interactive wizard and CI version for enabling Ralph in existing projects.

New commands:
- ralph-enable: Interactive 5-phase wizard for humans
- ralph-enable-ci: Non-interactive version with JSON output for CI/automation

New library components:
- lib/enable_core.sh: Shared logic for idempotency, project detection, templates
- lib/wizard_utils.sh: Interactive prompt utilities
- lib/task_sources.sh: Task import from beads, GitHub Issues, PRD documents

Features:
- Auto-detects project type (TypeScript, Python, Rust, Go)
- Auto-detects framework (Next.js, FastAPI, Django, Express)
- Imports tasks from beads, GitHub Issues, or PRD documents
- Generates .ralphrc project configuration file
- Idempotent: safe to run multiple times, respects existing files
- Exit codes: 0 (success), 1 (error), 2 (already enabled)

Updated:
- install.sh: Added new commands to global installation
- ralph_loop.sh: Loads .ralphrc configuration at startup

Tests: 75 new tests (30 enable_core + 23 task_sources + 22 integration)
Total: 396 tests passing (100% pass rate)

Closes #85, #121, #64, #87, #99

* fix(enable): address code review feedback

Fixes from PR #124 review:

1. sed -i portability (ralph_enable.sh:456)
   - Use portable sed + mv pattern instead of GNU-only sed -i

2. sed regex portability (lib/task_sources.sh)
   - Replace \s with POSIX [[:space:]] character class
   - Add sed -E flag for extended regex

3. jq availability check (ralph_enable_ci.sh:177)
   - Add check for jq when --json flag is used

4. Unused filter parameter (lib/task_sources.sh:44)
   - Pass filter to bd list --filter command

5. Word-splitting in select_multiple (ralph_enable.sh:322)
   - Return comma-separated indices instead of space-separated text
   - Update caller to parse indices correctly

6. Missing || true for check_existing_ralph (ralph_enable.sh:185)
   - Prevent set -e from exiting on non-zero return

7. select_multiple stdout corruption (lib/wizard_utils.sh)
   - Redirect interactive output to stderr
   - Only final result goes to stdout

8. Color variables not exported (lib/wizard_utils.sh:12)
   - Export WIZARD_* color variables for subshells

9. select_option infinite loop (lib/wizard_utils.sh:179)
   - Add guard for empty options array

* fix(tests): add missing mocks and exports for new enable feature

- Add RESPONSE_ANALYSIS_FILE export to test_session_continuity.bats setup
- Add mock ralph_enable.sh and ralph_enable_ci.sh to test_installation.bats
- Add mock lib files: enable_core.sh, wizard_utils.sh, task_sources.sh, timeout_utils.sh

All 396 tests now pass.

* fix(config): fix critical issues from PR review

1. .ralphrc Configuration Loading Fix:
   - Captured env var state BEFORE setting defaults with _env_* variables
   - load_ralphrc now only restores values explicitly set by environment
   - .ralphrc settings are now properly applied (not overwritten by defaults)

2. sed Command Injection Fix:
   - Replaced sed with awk for .ralphrc updates in ralph_enable.sh
   - awk -v pattern safely handles user input without shell injection risk

3. Shell Injection Fix in safe_create_file():
   - Replaced echo with printf '%s\n' for safer content handling
   - Prevents issues with backslashes, -n, and special characters

4. Specific Error Codes:
   - Added ENABLE_INVALID_ARGS=3 for argument errors
   - Added ENABLE_FILE_NOT_FOUND=4 for missing files
   - Added ENABLE_DEPENDENCY_MISSING=5 for missing deps (e.g., jq)
   - Added ENABLE_PERMISSION_DENIED=6 for permission errors
   - Updated ralph_enable.sh and ralph_enable_ci.sh to use specific codes

5. Added tests for .ralphrc loading pattern verification

Test count: 398 (up from 396)

* fix(enable): make --force flag actually overwrite existing files

The --force flag was accepted but safe_create_file() always skipped
existing files regardless of ENABLE_FORCE value.

Changes:
- safe_create_file() now checks ENABLE_FORCE environment variable
- When ENABLE_FORCE="true", overwrites existing files instead of skipping
- Added proper logging for overwrite operations

Added tests:
- Verify enable_ralph_in_directory actually changes file contents with --force
- Test safe_create_file overwrites when ENABLE_FORCE is true
- Test safe_create_file skips when ENABLE_FORCE is false

Test count: 400 (up from 398)

---------

Co-authored-by: Test User <test@example.com>
2026-01-25 14:37:25 -07:00
Test User
019b8c738a Merge main into fix/test-prd-import-version-handler
Resolved conflicts by keeping both:
- Updated comments mentioning .ralph/ subfolder (from main)
- Added --version handler to mock scripts (from PR #107)
2026-01-21 22:04:59 -07:00
Test User
f6791e431c chore(git): stop tracking .claude/settings.local.json
File was already in .gitignore but still being tracked.
Removed from index to respect gitignore entry.
2026-01-21 21:54:12 -07:00
Test User
d63f300c09 fix(session): clear exit signals on session reset (issue #91)
Root cause: Stale completion indicators in .exit_signals and .response_analysis
files persisted across sessions, causing premature exit when combined with
normal completion indicator increments.

Changes:
- Enhanced reset_session() to clear .exit_signals file (resets to empty structure)
- Enhanced reset_session() to remove .response_analysis file
- Session reset now comprehensively clears all exit-related state

Added 2 new tests:
- reset_session clears exit_signals file to prevent premature exit
- reset_session prevents issue #91 scenario (stale completion indicators)

Test count: 321 (up from 319)

Fixes #91
2026-01-21 21:53:08 -07:00
Test User
761db2f67d Merge main and apply code review fixes
Merged origin/main into PR branch and applied review feedback:

Review fixes:
- Guard against empty result_obj if jq fails (Macroscope)
- Prioritize result object's session_id over init message (CodeRabbit)
- Add regression test for arrays with session_id only in result element

Resolved conflicts:
- CLAUDE.md: Updated test count to 319

All 319 tests pass.
2026-01-21 21:42:29 -07:00
Test User
da1aed34c6 fix(analyzer,monitor): EXIT_SIGNAL detection and monitor paths (v0.10.1)
Fixes #113 - EXIT_SIGNAL not detected in JSON output format
Fixes #117 - ralph_monitor.sh uses wrong paths after v0.10.0 migration

Bug fixes:
- Parse EXIT_SIGNAL from .result field when Claude CLI returns JSON format
- Add safety circuit breaker: force exit after 5 consecutive completion indicators
- Fix checkbox parsing for indented markdown with POSIX [[:space:]]* pattern
- Update ralph_monitor.sh paths: status.json, logs/ralph.log, progress.json

Files changed:
- lib/response_analyzer.sh: Extract RALPH_STATUS from embedded .result text
- ralph_loop.sh: Safety circuit breaker + indented checkbox patterns
- ralph_monitor.sh: All paths updated for .ralph/ subfolder
- create_files.sh: Indented checkbox pattern consistency
- README.md: v0.10.1 changelog, version bump, test count update
- CLAUDE.md: Version bump to v0.10.1

All 310 tests pass.
2026-01-21 21:31:50 -07:00
zerone0x
5ce9bc81d7 fix(analyzer): handle Claude CLI JSON array output format
Claude Code CLI outputs a JSON array instead of a single object:
[{type: "system", ...}, {type: "assistant", ...}, {type: "result", ...}]

This caused parse_json_response to fail with "jq: invalid JSON text"
because it assumed the top-level JSON was an object.

Changes:
- Detect if JSON is an array before parsing
- Extract the "result" type message from the array
- Preserve session_id from init message for continuity
- Normalize to object format for existing parsing logic
- Clean up temporary file after processing

Fixes #112

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-21 22:56:53 +08:00
Frank Bria
9b19d70e35
feat(structure): migrate Ralph files to .ralph/ subfolder (#109)
* feat(structure): migrate Ralph files to .ralph/ subfolder

BREAKING CHANGE: Ralph configuration files now live in .ralph/ subfolder

This refactoring moves all Ralph-specific files into a hidden .ralph/
directory while keeping src/ at the project root. This improves
compatibility with existing tooling and keeps the project root clean.

Changes:
- Move PROMPT.md, @fix_plan.md, @AGENT.md to .ralph/
- Move specs/, logs/, docs/generated/, examples/ to .ralph/
- Move state files (.response_analysis, .circuit_breaker_state, etc.) to .ralph/
- Keep src/ at project root (unchanged)
- Add RALPH_DIR=".ralph" configuration variable
- Add ralph-migrate command for existing projects
- Create migrate_to_ralph_folder.sh migration script
- Update all path references in scripts and tests
- Update documentation (README.md, CLAUDE.md)

New project structure:
  project/
  ├── .ralph/           # Ralph configuration
  │   ├── PROMPT.md
  │   ├── @fix_plan.md
  │   ├── @AGENT.md
  │   ├── specs/
  │   ├── logs/
  │   └── docs/generated/
  └── src/              # Source code (unchanged)

Migration: Run `ralph-migrate` in existing projects to upgrade.

All 310 tests pass (100% pass rate).

* chore: add .claude/settings.local.json to .gitignore

* fix: address code review feedback for .ralph/ subfolder structure

Fixes multiple path-related issues identified in code review:

Test fixes:
- Fix create_sample_prompt to use $RALPH_DIR/PROMPT.md in test_session_continuity.bats
- Fix result_file path to use $RALPH_DIR/.json_parse_result in test_json_parsing.bats
- Fix @fix_plan.md and .response_analysis paths in test_cli_modern.bats
- Update templates directory missing test to account for global fallback

Template fix:
- Fix @fix_plan.md reference in templates/PROMPT.md to use .ralph/ prefix

Script fixes:
- Fix PROMPT_FILE comparison in ralph_loop.sh to use $RALPH_DIR/PROMPT.md
- Fix examples migration logic in migrate_to_ralph_folder.sh (remove premature mkdir)
- Move templates directory check AFTER cd in setup.sh (was checking wrong location)
- Add template directory validation with fallback to global templates

All 310 tests pass.

* Update migrate_to_ralph_folder.sh

Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>

* fix: address code review feedback for .ralph/ subfolder structure

Code Review Fixes:
- Fix test_json_parsing.bats: all result_file and session file paths now use $RALPH_DIR prefix
- Fix ralph_loop.sh help text: paths now show .ralph/.ralph_session, .ralph/.call_count, etc.
- Fix migrate_to_ralph_folder.sh:
  - Proper error handling for date command (separate local declaration)
  - Use cp -a source/. dest/ pattern to preserve dotfiles and attributes
  - Remove 2>/dev/null suppression to surface copy errors
- Update create_files.sh to use .ralph/ structure for embedded scripts
- Update .gitignore with all .ralph/ state file paths
- Add old structure detection in ralph_loop.sh with helpful migration message

Version Update:
- Bump to v0.10.0 (breaking change: structural reorganization)
- Update README.md and CLAUDE.md with new version and release notes
- Add ralph-migrate documentation to Key Commands section

All 310 tests pass.

---------

Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>
2026-01-20 23:22:30 -07:00
Frank Bria
0e95f67318
Add timeout command support for macOS (#108)
* feat(timeout): add cross-platform timeout support for macOS

Add portable timeout wrapper that automatically detects and uses the
appropriate timeout command based on the platform:
- Linux: Uses standard GNU `timeout` from coreutils
- macOS: Uses `gtimeout` from Homebrew coreutils

Changes:
- Add lib/timeout_utils.sh with detect_timeout_command() and
  portable_timeout() functions
- Update ralph_loop.sh to source timeout_utils.sh and use
  portable_timeout for Claude Code execution
- Update install.sh to check for coreutils on macOS and provide
  installation instructions
- Update test mocks to include gtimeout and portable_timeout
- Update README.md with macOS coreutils installation instructions
- Update CLAUDE.md with timeout_utils.sh documentation

Users on macOS now need to install coreutils: brew install coreutils

* Update model reference in opencode-review workflow

* Update model name in opencode-review workflow

* Update model version in opencode-review workflow

* Update model version in opencode-review workflow

* Update lib/timeout_utils.sh

Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>

* Update opencode-review.yml

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>
2026-01-20 18:40:21 -07:00
Marty
558b1518b5 fix(tests): add --version handler to mock claude commands in prd_import tests
Mock claude commands in test_prd_import.bats were hanging on test 240
because they started with 'cat > /dev/null' which blocks waiting for stdin.
When ralph_import.sh calls 'claude --version' during dependency check,
no stdin is provided, causing indefinite hang.

Changes:
- Added --version flag handler to all 7 mock claude command generators
- Handler returns "Claude Code CLI version 2.0.80" and exits before stdin read
- Fixes hang in test 240 and ensures all 33 prd_import tests pass

This fix allows the quickstart installation to complete successfully
without test stalls.

Fixes #N/A (discovered during quickstart installation)
2026-01-20 21:34:00 +00:00
Test User
509a9699a8 fix(workflow) Patch opencode bug in GitHub Actions timeout 2026-01-13 19:44:08 -07:00
Test User
dd694ece49 docs(readme): update for v0.9.9 with EXIT_SIGNAL gate and uninstall script
Major updates:
- Version bumped to v0.9.9
- Test count updated to 308 (from 276)
- Added v0.9.9 release notes: EXIT_SIGNAL gate fix, uninstall script, session expiration
- New "Uninstalling Ralph" section with dedicated uninstall.sh
- Updated "Intelligent Exit Detection" with dual-condition check explanation
- Added EXIT_SIGNAL decision table to Configuration section
- New troubleshooting entries: "Premature Exit" and "Session Expired"
- Updated test coverage breakdown (164 unit + 144 integration)
- Added "Clean Uninstall" to Features list
- Updated Command Reference with ./uninstall.sh
2026-01-12 22:11:19 -07:00
Frank Bria
aca3670cc7
fix(loop): respect Claude's EXIT_SIGNAL when checking completion indicators (#90)
* fix(loop): respect Claude's EXIT_SIGNAL when checking completion indicators

The should_exit_gracefully() function was exiting prematurely based solely
on completion_indicators heuristics, ignoring Claude's explicit EXIT_SIGNAL
in the RALPH_STATUS block. This caused premature exits during productive
iterations when Claude reported work in progress.

Changes:
- ralph_loop.sh: Added dual-condition check requiring BOTH completion
  indicators >= 2 AND exit_signal == true before exiting
- response_analyzer.sh: Added explicit_exit_signal_found flag to prevent
  natural language heuristics from overriding Claude's explicit intent
- Added 14 new tests (10 unit + 4 integration) covering EXIT_SIGNAL behavior

Decision matrix:
| indicators >= 2 | EXIT_SIGNAL | Result |
|-----------------|-------------|--------|
| true            | true        | Exit   |
| true            | false       | Continue |
| true            | missing     | Continue (defaults to false) |
| false           | true        | Continue (threshold not met) |

Fixes premature exit bug during productive development iterations.

* Update lib/response_analyzer.sh

Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>

* test(exit): add STATUS=COMPLETE vs EXIT_SIGNAL=false conflict test

docs(exit): update CLAUDE.md with EXIT_SIGNAL gate documentation

- Added test for STATUS=COMPLETE with EXIT_SIGNAL=false conflict
  (EXIT_SIGNAL takes precedence, allowing phase completion without loop exit)
- Updated "Intelligent Exit Detection" section with dual-condition explanation
- Added "Completion Indicators with EXIT_SIGNAL Gate" section with decision table
- Documented conflict resolution behavior and implementation details

---------

Co-authored-by: Test User <test@example.com>
Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>
2026-01-12 22:07:24 -07:00
Zander
3e8d3fdcde
feat: add dedicated uninstall.sh script (#45)
* feat: add dedicated uninstall.sh script

Add a standalone uninstall script that provides:
- Safety confirmation prompt before removal (skip with -y/--yes)
- Installation check to verify Ralph is installed
- Removal plan display showing exactly what will be removed
- Consistent styling matching install.sh (colors, logging)
- Help option (-h/--help) for usage information
- Preserves project directories created with ralph-setup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: add function documentation to uninstall.sh

Address CodeRabbit review comments:
- Add documentation comments to all functions (log, check_installation,
  show_removal_plan, confirm_uninstall, remove_commands, remove_ralph_home, main)
- Improve check_installation to detect partial installations by checking
  all Ralph commands, not just the main ralph command

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: use safe arithmetic to avoid set -e failure

Replace ((removed++)) with removed=$((removed + 1)) to prevent
script termination when removed is 0, as post-increment returns
exit code 1 when the expression value is 0 under set -e.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 20:46:57 -07:00
Frank Bria
3dc3479c27
feat(session): implement session expiration with configurable timeout (#84)
* Reapply "feat(session): implement session expiration with configurable timeout (#83)"

This reverts commit 1ba55a4b9c.

* fix(session): address code review feedback

- Fix integer overflow: return -1 from get_session_file_age_hours on stat
  failure instead of 0, preventing false expiration
- Handle stat failure in init_claude_session with WARN log
- Add comprehensive documentation for return values and expiration strategy
- Add 6 behavioral integration tests that verify actual functionality
- Add inline comments explaining 24-hour default rationale

Test count: 286 → 292 (100% pass rate)

* fix(test): use grep-based verification to fix CI failures

Tests that sourced ralph_loop.sh with --help flag failed in GitHub
Actions due to BATS environment differences. Changed behavioral tests
to grep-based code verification that checks implementation patterns
exist without executing the script.

* fix(test): guard main with BASH_SOURCE for safe sourcing

- Add BASH_SOURCE check to only execute main when script is run directly
- Update tests to source script without --help flag
- Convert grep-based verification tests back to functional tests
- Fixes CI failures caused by script execution during sourcing

---------

Co-authored-by: Test User <test@example.com>
2026-01-10 19:40:38 -07:00
Test User
1ba55a4b9c Revert "feat(session): implement session expiration with configurable timeout (#83)"
This reverts commit 9110e3d3ad.
2026-01-10 19:11:15 -07:00
Frank Bria
9110e3d3ad
feat(session): implement session expiration with configurable timeout (#83)
- Add CLAUDE_SESSION_EXPIRY_HOURS configuration variable (default: 24)
- Add get_session_file_age_hours() helper with cross-platform stat support
- Modify init_claude_session() to check session age and remove expired sessions
- Add --session-expiry CLI flag to configure expiration (positive integers only)
- Update help text with new option and example
- Add 10 new tests for session expiration (TDD approach)

Closes #51

Test count: 276 → 286 (100% pass rate)

Co-authored-by: Test User <test@example.com>
2026-01-10 19:10:29 -07:00
Test User
81fac49933 docs(status): mark #27 badges complete 2026-01-10 18:47:34 -07:00
Test User
369e118a27 docs(readme): add CI and license badges
- Add GitHub Actions CI badge (dynamic, links to workflow)
- Add MIT License badge (links to LICENSE file)
- Add GitHub Issues badge (dynamic count)
- Keep Awesome Claude Code and X follow badges
- Remove redundant status badge, keep version and tests
2026-01-10 18:47:02 -07:00
Test User
253c8888aa docs(status): mark #24 and #26 complete 2026-01-10 18:44:49 -07:00
Test User
0ff60124fd docs(readme): add link to TESTING.md guide 2026-01-10 18:44:23 -07:00
Test User
94cb7493db docs(status): mark CONTRIBUTING.md guide complete 2026-01-10 18:22:37 -07:00
Test User
d0cb80f670 docs: add comprehensive contributor guide
- Create CONTRIBUTING.md with 8 sections covering the full contributor
  journey: Getting Started, Development Workflow, Code Style, Testing,
  PR Process, Code Review, Quality Standards, and Community Guidelines
- Include workflow diagram, quality gates table, and test commands reference
- Update README.md to reference CONTRIBUTING.md, consolidating duplicate
  contributor information into the dedicated guide
2026-01-10 17:03:12 -07:00