Skip to content

feat: enhance live monitoring with jq filters, dashboard, and tmux fallback#209

Open
timothy-20 wants to merge 5 commits intofrankbria:mainfrom
timothy-20:feat/live-monitoring-enhancement
Open

feat: enhance live monitoring with jq filters, dashboard, and tmux fallback#209
timothy-20 wants to merge 5 commits intofrankbria:mainfrom
timothy-20:feat/live-monitoring-enhancement

Conversation

@timothy-20
Copy link
Contributor

@timothy-20 timothy-20 commented Feb 28, 2026

Summary

Enhances Ralph's live monitoring capabilities across three areas:

  • jq filter verbosity: New build_jq_filter() function with 3-level output filtering (minimal/normal/verbose), configurable via RALPH_LIVE_VERBOSITY env var, .ralphrc, or --live-verbosity CLI flag
  • Monitor dashboard: Added "Live Claude Output" section to ralph_monitor.sh that displays the last 5 lines from .ralph/live.log with 72-char truncation
  • tmux fallback: --monitor now gracefully falls back to --live mode when tmux is not installed, instead of exiting with an error

Verbosity levels

Level Shows
minimal Text output + tool names
normal (default) + tool errors, stop reason, session errors, rate limit warnings
verbose + thinking blocks, successful tool results, input JSON fragments

Changed files

File Change
ralph_loop.sh build_jq_filter(), setup_fallback_monitor(), check_tmux_available() refactor, CLI flag, env wiring
ralph_monitor.sh Live Claude Output section (purple, tail -5, 72-char truncation)
lib/enable_core.sh RALPH_LIVE_VERBOSITY in generate_ralphrc()
setup.sh RALPH_LIVE_VERBOSITY in inline .ralphrc
templates/ralphrc.template RALPH_LIVE_VERBOSITY="normal" default
tests/helpers/fixtures.bash 5 NDJSON fixtures for jq filter tests
tests/unit/test_cli_modern.bats 31 new tests (68 → 99)
CLAUDE.md Test counts, config vars, CLI options updated

Test plan

  • All 599 tests pass (npm test)
  • build_jq_filter produces valid jq for all 3 levels + unknown fallback
  • Each verbosity level filters correct event types (positive + negative tests)
  • rate_limit_event rendering verified for normal/verbose, excluded from minimal
  • Monitor dashboard references live.log and handles missing file gracefully
  • check_tmux_available uses return not exit
  • Dispatch logic has fallback path when tmux unavailable
  • --live-verbosity CLI flag validates input and rejects invalid values
  • .ralphrc and setup.sh templates include RALPH_LIVE_VERBOSITY
  • Manual integration test with ralph --monitor and ralph --live --live-verbosity verbose

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added --live-verbosity CLI option to control live output detail level (minimal, normal, verbose).
    • Introduced RALPH_LIVE_VERBOSITY configuration variable for setting default verbosity preferences.
    • Enhanced live output dashboard to display Claude output logs in real-time.
    • Graceful fallback to live output mode when tmux is unavailable.
  • Tests

    • Expanded test coverage for live verbosity, CLI options, and fallback behavior.

timothy-20 and others added 5 commits March 1, 2026 00:44
Add three-level live output verbosity control for streaming mode:

- minimal: text + tool names only (original behavior)
- normal: + tool errors, stop reasons, session errors, rate limits
- verbose: + thinking content, input fragments, successful tool results

Implementation:
- build_jq_filter() function replaces inline jq filter
- RALPH_LIVE_VERBOSITY config with env > .ralphrc > default priority
- --live-verbosity CLI flag with validation
- tmux session forwards verbosity setting
- Templates and setup.sh updated with new config option
- 23 new tests with NDJSON stream fixtures
- Fix existing test that broke due to rate_limit_event in jq filter
Add Live Claude Output section to ralph_monitor.sh that displays
the last 5 lines from .ralph/live.log with 72-char truncation.
Shows guidance message when live.log is absent.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When tmux is not installed, --monitor now falls back to live output
mode instead of exiting with an error. Displays install instructions
and runs with LIVE_OUTPUT=true.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update test count (568 → 596), add RALPH_LIVE_VERBOSITY config
variable, add --live-verbosity CLI option, and update
test_cli_modern.bats description with live monitoring tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
W1: Add missing argument guard for --live-verbosity flag, consistent
    with --session-expiry pattern.
W2: Remove unreachable exit 0 after main() call in
    setup_fallback_monitor().
W3: Add rate_limit_event NDJSON fixture and 3 tests verifying
    normal/verbose show warning, minimal does not.
S3: Fix misplaced comment in fixtures.bash — move create_test_project
    docstring back above its function definition.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 28, 2026

Walkthrough

This PR introduces live output verbosity control by adding a new RALPH_LIVE_VERBOSITY configuration variable (minimal, normal, verbose) and corresponding --live-verbosity CLI flag. Changes include jq-filter parameterization for streaming output, a tmux fallback monitor path, and expanded test coverage.

Changes

Cohort / File(s) Summary
Configuration & Documentation
CLAUDE.md, lib/enable_core.sh, setup.sh, templates/ralphrc.template
Added RALPH_LIVE_VERBOSITY variable declaration, initialization with default "normal", and CLI option documentation (--live-verbosity minimal|normal|verbose).
Live Streaming Pipeline
ralph_loop.sh
Introduced build_jq_filter() function to generate verbosity-aware jq filters; added setup_fallback_monitor() for tmux-unavailable fallback; wired --live-verbosity CLI flag through config loading, tmux setup, and Claude command invocation; added conditional tmux fallback with LIVE_OUTPUT mode switching.
Monitor Dashboard
ralph_monitor.sh
Added LIVE_LOG_FILE variable and integrated live Claude output display (up to 5 lines, 72-char truncation) into status dashboard with conditional messaging for file existence and content state.
Test Infrastructure
tests/helpers/fixtures.bash, tests/unit/test_cli_modern.bats
Added NDJSON stream fixture generators (basic events, errors, thinking blocks, rate-limits) and comprehensive test suite covering build_jq_filter outputs, verbosity modes, tmux fallback, live.log integration, CLI flag parsing, and API limit detection.

Sequence Diagram

sequenceDiagram
    participant User as User (CLI)
    participant Config as Config System
    participant Parser as CLI Parser
    participant Filter as build_jq_filter()
    participant Stream as Streaming Pipeline
    participant Monitor as ralph_monitor.sh

    User->>Parser: --live-verbosity minimal|normal|verbose
    Parser->>Config: Read .ralphrc / env override
    Config->>Config: RALPH_LIVE_VERBOSITY = "normal" (default)
    Parser->>Filter: build_jq_filter(RALPH_LIVE_VERBOSITY)
    Filter-->>Parser: jq filter string (verbosity-aware)
    Parser->>Stream: Execute Claude with jq filter
    Stream->>Stream: Stream output with filter (exclude/include fields by verbosity)
    Stream->>Monitor: Write to LIVE_LOG_FILE
    Monitor->>Monitor: Display up to 5 lines of live output
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #179 — Modifies live-streaming pipeline in ralph_loop.sh with errexit/PIPESTATUS guard and streaming logic overlaps.
  • PR #125 — Introduces LIVE_LOG_FILE and jq-based streaming pipeline that this PR parameterizes with verbosity control.
  • PR #184 — Overlaps on test fixtures (rate-limit detection and sample stream JSON creation in tests/helpers/fixtures.bash).

Poem

🐰 Verbosity flows where the streams do grow,
Minimal whispers or verbose show,
A jq filter dances with just the right grace,
While monitors watch from their cozy place!

🚥 Pre-merge checks | ✅ 3
✅ 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 accurately summarizes the three main enhancements in the changeset: jq filters for live monitoring verbosity, a new dashboard section, and tmux fallback handling.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
setup.sh (1)

55-115: ⚠️ Potential issue | 🟠 Major

Set restrictive permissions on .ralphrc after generation.

.ralphrc is created in this block, but no permission hardening is applied. This leaves config readable by other users on shared systems.

🔐 Proposed fix
 if [[ -f "$LIB_DIR/enable_core.sh" ]]; then
@@
 RALPHRCEOF
 fi
+
+# Protect project configuration (may contain sensitive settings)
+chmod 600 .ralphrc

As per coding guidelines Set restrictive permissions (600) on .ralphrc file in setup.sh and ralph_enable.sh to protect sensitive configuration.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@setup.sh` around lines 55 - 115, The .ralphrc file is created without
permission hardening; after any creation path (the generate_ralphrc pipeline
that writes to .ralphrc and the fallback here-doc block terminated by RALPHRCEOF
in setup.sh) add a chmod 600 .ralphrc to restrict it to the owner, and mirror
the same change in ralph_enable.sh where .ralphrc may be created or written;
ensure both the generate_ralphrc -> sed -> .ralphrc branch and the here-doc
block (and any write/tee calls in ralph_enable.sh) are followed by a chmod 600
to enforce restrictive permissions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ralph_loop.sh`:
- Around line 1909-1913: Update the help string for the -m, --monitor option so
it no longer says "requires tmux"; instead indicate it will start a tmux session
if available and fall back to non-tmux monitoring when tmux is absent (e.g.,
change the "-m, --monitor           Start with tmux session and live monitor
(requires tmux)" line to mention fallback behavior). Locate the option text for
"-m, --monitor" and adjust the wording to reflect the new behavior (reference
the "--monitor" / "-m" option and "tmux" in your edit).
- Around line 372-382: The fallback function setup_fallback_monitor() currently
sets LIVE_OUTPUT=true and then directly calls main(), causing main() to run
twice because the script's entry block also calls main(); remove the direct call
to main() from setup_fallback_monitor() and make the function simply set
LIVE_OUTPUT=true and return so the outer entry logic invokes main() exactly once
(ensure no other callers rely on setup_fallback_monitor() to invoke main()).

In `@tests/unit/test_cli_modern.bats`:
- Around line 1269-1276: The test "--live-verbosity rejects invalid values"
currently inspects the parser help text instead of exercising runtime
validation; change it to actually run the CLI with an invalid verbosity value
and assert failure: use the existing local script variable
(script="${BATS_TEST_DIRNAME}/../../ralph_loop.sh") and invoke it via Bats' run
with arguments including --live-verbosity invalid_value (e.g. "super-verbose"),
then assert a non-zero exit status (run exit code != 0) and check that stderr or
output contains an appropriate error message about invalid verbosity (match
"invalid" or the allowed choices minimal|normal|verbose) so the test fails if
runtime rejection regresses.

---

Outside diff comments:
In `@setup.sh`:
- Around line 55-115: The .ralphrc file is created without permission hardening;
after any creation path (the generate_ralphrc pipeline that writes to .ralphrc
and the fallback here-doc block terminated by RALPHRCEOF in setup.sh) add a
chmod 600 .ralphrc to restrict it to the owner, and mirror the same change in
ralph_enable.sh where .ralphrc may be created or written; ensure both the
generate_ralphrc -> sed -> .ralphrc branch and the here-doc block (and any
write/tee calls in ralph_enable.sh) are followed by a chmod 600 to enforce
restrictive permissions.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6ff27b4 and d22a24c.

📒 Files selected for processing (8)
  • CLAUDE.md
  • lib/enable_core.sh
  • ralph_loop.sh
  • ralph_monitor.sh
  • setup.sh
  • templates/ralphrc.template
  • tests/helpers/fixtures.bash
  • tests/unit/test_cli_modern.bats

Comment on lines +372 to +382
# Fallback when tmux is not available: run with live output only
setup_fallback_monitor() {
echo "tmux is not installed. Falling back to live output mode."
echo "Install tmux for the full monitoring dashboard:"
echo " Ubuntu/Debian: sudo apt-get install tmux"
echo " macOS: brew install tmux"
echo " CentOS/RHEL: sudo yum install tmux"
echo ""
LIVE_OUTPUT=true
main
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fallback monitor currently triggers main() twice.

Line 381 calls main inside setup_fallback_monitor(), and main is called again at Line 2089 in the entry block. After a normal loop exit, fallback mode can immediately restart and consume extra API calls.

🐛 Proposed fix
 setup_fallback_monitor() {
     echo "tmux is not installed. Falling back to live output mode."
@@
     echo "  CentOS/RHEL: sudo yum install tmux"
     echo ""
     LIVE_OUTPUT=true
-    main
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ralph_loop.sh` around lines 372 - 382, The fallback function
setup_fallback_monitor() currently sets LIVE_OUTPUT=true and then directly calls
main(), causing main() to run twice because the script's entry block also calls
main(); remove the direct call to main() from setup_fallback_monitor() and make
the function simply set LIVE_OUTPUT=true and return so the outer entry logic
invokes main() exactly once (ensure no other callers rely on
setup_fallback_monitor() to invoke main()).

Comment on lines 1909 to 1913
-m, --monitor Start with tmux session and live monitor (requires tmux)
-v, --verbose Show detailed progress updates during execution
-l, --live Show Claude Code output in real-time (auto-switches to JSON output)
--live-verbosity LEVEL Set live output verbosity: minimal, normal, verbose (default: $RALPH_LIVE_VERBOSITY)
-t, --timeout MIN Set Claude Code execution timeout in minutes (default: $CLAUDE_TIMEOUT_MINUTES)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Help text for --monitor is now stale.

--monitor no longer strictly requires tmux because fallback mode exists, but help still says “requires tmux”.

📝 Proposed fix
-    -m, --monitor           Start with tmux session and live monitor (requires tmux)
+    -m, --monitor           Start with tmux monitor (falls back to --live if tmux is unavailable)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ralph_loop.sh` around lines 1909 - 1913, Update the help string for the -m,
--monitor option so it no longer says "requires tmux"; instead indicate it will
start a tmux session if available and fall back to non-tmux monitoring when tmux
is absent (e.g., change the "-m, --monitor           Start with tmux session and
live monitor (requires tmux)" line to mention fallback behavior). Locate the
option text for "-m, --monitor" and adjust the wording to reflect the new
behavior (reference the "--monitor" / "-m" option and "tmux" in your edit).

Comment on lines +1269 to +1276
@test "--live-verbosity rejects invalid values" {
local script="${BATS_TEST_DIRNAME}/../../ralph_loop.sh"
# The parser checks for minimal|normal|verbose
run grep -A3 '\-\-live-verbosity)' "$script"
[[ "$output" == *"minimal"* ]]
[[ "$output" == *"normal"* ]]
[[ "$output" == *"verbose"* ]]
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

--live-verbosity invalid-value test is structural, not behavioral.

This test currently passes by matching parser text, even if runtime rejection regresses. It should execute the script with an invalid value and assert failure.

🧪 Proposed fix
 `@test` "--live-verbosity rejects invalid values" {
-    local script="${BATS_TEST_DIRNAME}/../../ralph_loop.sh"
-    # The parser checks for minimal|normal|verbose
-    run grep -A3 '\-\-live-verbosity)' "$script"
-    [[ "$output" == *"minimal"* ]]
-    [[ "$output" == *"normal"* ]]
-    [[ "$output" == *"verbose"* ]]
+    run bash "${BATS_TEST_DIRNAME}/../../ralph_loop.sh" --live-verbosity invalid
+    assert_failure
+    [[ "$output" == *"--live-verbosity must be"* ]]
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@test "--live-verbosity rejects invalid values" {
local script="${BATS_TEST_DIRNAME}/../../ralph_loop.sh"
# The parser checks for minimal|normal|verbose
run grep -A3 '\-\-live-verbosity)' "$script"
[[ "$output" == *"minimal"* ]]
[[ "$output" == *"normal"* ]]
[[ "$output" == *"verbose"* ]]
}
`@test` "--live-verbosity rejects invalid values" {
run bash "${BATS_TEST_DIRNAME}/../../ralph_loop.sh" --live-verbosity invalid
assert_failure
[[ "$output" == *"--live-verbosity must be"* ]]
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/test_cli_modern.bats` around lines 1269 - 1276, The test
"--live-verbosity rejects invalid values" currently inspects the parser help
text instead of exercising runtime validation; change it to actually run the CLI
with an invalid verbosity value and assert failure: use the existing local
script variable (script="${BATS_TEST_DIRNAME}/../../ralph_loop.sh") and invoke
it via Bats' run with arguments including --live-verbosity invalid_value (e.g.
"super-verbose"), then assert a non-zero exit status (run exit code != 0) and
check that stderr or output contains an appropriate error message about invalid
verbosity (match "invalid" or the allowed choices minimal|normal|verbose) so the
test fails if runtime rejection regresses.

Copy link
Owner

@frankbria frankbria left a comment

Choose a reason for hiding this comment

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

Good feature — the verbosity-controlled jq filters, dashboard enhancement, and tmux fallback are all well-implemented with thorough tests (31 new).

Must fix before merge:

  1. setup_fallback_monitor() calls main() directly — this creates a double-invocation risk since the script's entry block at the bottom also calls main(). Instead, the function should set LIVE_OUTPUT=true and return, letting the existing entry logic call main().

Should fix:

  1. Help text still says --monitor "(requires tmux)" but the behavior now falls back gracefully. Update the help text to reflect the new fallback behavior.

  2. The --live-verbosity rejects invalid values test only greps the source file for validation patterns rather than exercising the CLI with an actual invalid value. Consider a runtime test.

Otherwise the code quality is high — clean separation of build_jq_filter(), proper env-var precedence, and synchronized template/documentation updates.

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.

2 participants