feat(live): show tool call details in streaming output#253
feat(live): show tool call details in streaming output#253visigoth wants to merge 1 commit intofrankbria:mainfrom
Conversation
WalkthroughUpdated the LIVE-mode jq filter in Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 1563-1581: The tool-summary jq expression only strips newlines and
truncates for the "Bash" branch; update the other branches ("Read", "Write",
"Edit", "Glob", "Grep", "Agent") so their values are normalized the same way by
replacing raw emissions like (.input.file_path // ""), (.input.pattern // ""),
and (.input.description // "") with the same pipeline used for Bash (fallback to
"", split on "\n", take first line, truncate to 120 chars) in the jq string
construction around the tool summary generation.
- Around line 1576-1577: The current conditional only handles subagents named
"Agent" and drops descriptions from older versions that use "Task"; update the
condition that checks .name (the clause currently written as .name == "Agent")
to accept both "Agent" and "Task" (e.g., use a logical OR or an IN check so the
branch triggers for either name) and keep the existing extraction of
(.input.description // "") so the summary includes the description for both tool
names.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
7767280 to
90b904d
Compare
|
Both CodeRabbit findings addressed in the force-pushed commit:
Smoke-tested the filter directly with |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 1570-1584: The logging code that builds the tool-line (the
expression that checks .name == "Bash"/"Agent"/etc. and pulls
.input.command/.input.description) is emitting raw tool arguments into logs;
change it to redact or summarize sensitive content by default: replace direct
uses of (.input.command/.input.description/.input.file_path/.input.pattern) with
a sanitizer function (e.g., redact_sensitive()) that strips/obfuscates tokens,
secrets, long hex strings, URLs, emails, and common key=secret patterns and
returns a short safe summary (or "[REDACTED]" when unknown), and add an explicit
opt-in flag (e.g., ENABLE_VERBOSE_TOOL_ARGS) so full raw arguments are only
logged when explicitly enabled; update the branches for "Bash" and "Agent" to
call that sanitizer (or produce one-line summaries like "<command redacted>" /
first non-sensitive word) instead of writing raw input and keep the 120-char cut
as a secondary guard.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| "\n⚡ [" + .name + "] " + ( | ||
| ( | ||
| if .name == "Bash" then | ||
| (.input.command // "") | ||
| elif .name == "Read" or .name == "Write" or .name == "Edit" then | ||
| (.input.file_path // "") | ||
| elif .name == "Glob" or .name == "Grep" then | ||
| (.input.pattern // "") | ||
| elif .name == "Agent" or .name == "Task" then | ||
| (.input.description // "") | ||
| else | ||
| "" | ||
| end | ||
| ) | split("\n") | .[0] | .[0:120] | ||
| ) + "\n" |
There was a problem hiding this comment.
Don't log raw tool arguments by default.
This branch now emits first-line Bash commands and Agent descriptions straight into the live pane/log, so any token, secret, URL, username, or prompt text carried in tool input gets persisted to disk. The 120-char cutoff does not materially reduce that exposure. Please redact common secret-bearing patterns or make argument-level summaries explicitly opt-in instead of always logging them.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@ralph_loop.sh` around lines 1570 - 1584, The logging code that builds the
tool-line (the expression that checks .name == "Bash"/"Agent"/etc. and pulls
.input.command/.input.description) is emitting raw tool arguments into logs;
change it to redact or summarize sensitive content by default: replace direct
uses of (.input.command/.input.description/.input.file_path/.input.pattern) with
a sanitizer function (e.g., redact_sensitive()) that strips/obfuscates tokens,
secrets, long hex strings, URLs, emails, and common key=secret patterns and
returns a short safe summary (or "[REDACTED]" when unknown), and add an explicit
opt-in flag (e.g., ENABLE_VERBOSE_TOOL_ARGS) so full raw arguments are only
logged when explicitly enabled; update the branches for "Bash" and "Agent" to
call that sanitizer (or produce one-line summaries like "<command redacted>" /
first non-sensitive word) instead of writing raw input and keep the 120-char cut
as a secondary guard.
frankbria
left a comment
There was a problem hiding this comment.
The enriched live feed is a nice improvement — seeing ⚡ [Bash] git status --short instead of a blank marker is much more useful. A few things to address before merging:
Blocking
Sensitive data in logs (security)
The jq filter emits raw tool arguments — Bash commands, file paths, grep patterns — directly into the live log. In practice these can contain secrets: aws configure set aws_secret_access_key ..., tokens passed as env vars, or credentials in file paths. Recommend either:
- Adding a sanitizer that redacts common secret patterns (e.g., long hex/base64 strings,
key=valuewhere key contains "secret"/"token"/"password"), or - Gating full argument output behind an opt-in flag like
ENABLE_VERBOSE_TOOL_ARGS=trueand emitting a safe summary by default (e.g. the command verb only for Bash)
This is particularly important since --live and --monitor output is often captured to a log file.
Non-blocking but please fix
Inconsistent normalization across tool branches
Only the Bash branch strips newlines and truncates to 120 chars. Read, Write, Edit, Glob, Grep, and Agent emit raw values that can contain newlines or be arbitrarily long. Apply the same normalization pipeline to all branches.
Missing Task tool name
The Agent branch only matches .name == "Agent". Older Claude CLI versions use "Task" as the tool name. Change the condition to match both:
elif .name == "Agent" or .name == "Task" thenAlso: please rebase
PR #256 (a 1-line crash fix in ralph_loop.sh) is being merged first. Please rebase this branch onto main after that lands, since both touch ralph_loop.sh.
Once the security concern is addressed and the other items fixed, happy to re-review.
The jq filter only showed tool names (⚡ [Bash]) with no arguments, making live mode appear empty when Claude does mostly tool calls. Now shows two levels of feedback: - ⚙ Bash... (immediate, from stream_event content_block_start) - ⚡ [Bash] actual command here (full args, from assistant message) Also removes stdbuf dependency check since stdbuf was removed in prior commit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
90b904d to
57fe9c7
Compare
|
Tool argument details are now opt-in via Default behavior ( Opt-in ( Implementation: the flag is passed into the jq filter as |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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`:
- Line 77: The LIVE_SHOW_TOOL_ARGS variable is undocumented, defaults to false,
and is bypassing the _env_* capture/restore flow; update the script so this
feature is discoverable and precedence-safe: add LIVE_SHOW_TOOL_ARGS handling
into load_ralphrc() (respecting env > .ralphrc precedence and ensuring it
participates in the _env_* capture/restore flow), expose it in show_help()
and/or add an explicit --show-tool-args CLI flag that sets LIVE_SHOW_TOOL_ARGS,
and update any places that read LIVE_SHOW_TOOL_ARGS (e.g., where the ⚡ [Tool]
output is emitted) to follow the new precedence and documented behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| DRY_RUN="${DRY_RUN:-false}" # Simulate loop without making actual Claude API calls | ||
| ENABLE_NOTIFICATIONS="${ENABLE_NOTIFICATIONS:-false}" # Enable desktop notifications; set true or use --notify flag | ||
| ENABLE_BACKUP="${ENABLE_BACKUP:-false}" # Enable automatic git backups before each loop; set true or use --backup flag | ||
| LIVE_SHOW_TOOL_ARGS="${LIVE_SHOW_TOOL_ARGS:-false}" # Show tool arguments in live streaming output (file paths, commands, patterns) |
There was a problem hiding this comment.
LIVE_SHOW_TOOL_ARGS is effectively hidden right now.
This defaults to false, has no CLI/help path, and skips the _env_* capture/restore flow. In practice, --live / --monitor users still just get a second ⚡ [Tool] marker unless they know to set an undocumented knob, and exported values can be overridden by .ralphrc even though the rest of the script treats environment as highest priority.
♻️ Minimal direction
+_env_LIVE_SHOW_TOOL_ARGS="${LIVE_SHOW_TOOL_ARGS:-}"
...
LIVE_SHOW_TOOL_ARGS="${LIVE_SHOW_TOOL_ARGS:-false}"Then mirror that in load_ralphrc() and expose the setting in show_help() or via an explicit --show-tool-args flag so the feature is discoverable and precedence-safe.
As per coding guidelines, "Documentation MUST remain synchronized with codebase: inline script comments for all functions, README updates for features, template file updates for patterns, and CLAUDE.md updates for new commands and behaviors".
Also applies to: 1610-1610
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@ralph_loop.sh` at line 77, The LIVE_SHOW_TOOL_ARGS variable is undocumented,
defaults to false, and is bypassing the _env_* capture/restore flow; update the
script so this feature is discoverable and precedence-safe: add
LIVE_SHOW_TOOL_ARGS handling into load_ralphrc() (respecting env > .ralphrc
precedence and ensuring it participates in the _env_* capture/restore flow),
expose it in show_help() and/or add an explicit --show-tool-args CLI flag that
sets LIVE_SHOW_TOOL_ARGS, and update any places that read LIVE_SHOW_TOOL_ARGS
(e.g., where the ⚡ [Tool] output is emitted) to follow the new precedence and
documented behavior.
|
Looks like you still need to rebase. |
Summary
Improves Ralph's
--live/--monitorstreaming output so the operator can actually see what Claude is doing during a loop iteration, not just that a tool was invoked.Before this change, the streaming
jqfilter only had access tostream_event content_block_startevents, which carry the tool name but no arguments (the input is delivered later as deltas). The result on screen was a blank⚡ [Bash]marker with no command, file path, or pattern — useful for confirming activity but not for following along.This PR keeps the immediate "tool starting" indicator and adds a richer second pass driven by full
assistantmessages, which arrive at the end of each turn with complete tool inputs.What changes in the live feed
⚙ Bash...— confirms a tool just started, with no args yet.⚡ [Bash] git status --short— the full first-line summary, truncated to 120 chars.Bash→ first line ofcommand, capped at 120 charsRead/Write/Edit→file_pathGlob/Grep→patternAgent→description🚀 Agent:and⚙markers for a less spread-out feed.Files
ralph_loop.sh— single-file change to thejqfilter inside the live streaming pipeline. +38 / -3.Why it's safe
emptyfor unknown tool types, so future tools won't break the filter.stream_eventbranch is preserved, so the immediate "tool started" indicator still fires even before the assistant message arrives.Test plan
ralph --monitoragainst a project that triggers a mix ofBash,Read,Edit, andGrepcalls — confirm each call shows a meaningful summary lineralph --live(without tmux) shows the same enriched feedBashcommand longer than 120 chars is truncated, not wrappedBashheredoc shows only the first line in the live feedAgent) invocations show the description stringnpm teststill passesSummary by CodeRabbit