fix(shared): hide tool_progress heartbeat events from chat delivery - #1094
Merged
Conversation
서브에이전트(sidechain)가 오래 걸리는 도구를 실행할 때 SDK가 주기적으로 내보내는 tool_progress heartbeat 이벤트가 isClaudeChatVisibleMessage()의 기본 통과 분기를 거쳐 raw JSON 그대로 채팅에 노출되던 문제를 고친다. rate_limit_event 필터링(tiann#423)과 동일한 패턴으로 타입 전체를 deny한다.
There was a problem hiding this comment.
Findings
- No issues found.
Questions
- None.
Summary
- Review mode: initial. Reviewed the full diff for
shared/src/messages.tsandcli/src/claude/utils/chatVisibility.test.ts; no high-confidence correctness, security, regression, performance, or maintainability issues found. Residual risk: runtime behavior oftool_progresspayloads could not be exercised locally in this workflow environment.
Testing
- Not run:
bun run test cli/src/claude/utils/chatVisibility.test.tsfailed becausebunis not installed in this runner shell.
HAPI Bot
swear01
added a commit
to swear01/hapi
that referenced
this pull request
Jul 28, 2026
fix(shared): hide tool_progress heartbeat events from chat delivery
swear01
added a commit
to swear01/hapi
that referenced
this pull request
Jul 29, 2026
fix(shared): hide tool_progress heartbeat events from chat delivery
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
While a sidechain (subagent, Task tool) runs a long Bash command, the Claude
Agent SDK periodically emits a
tool_progressheartbeat event on thetranscript/stream.
isClaudeChatVisibleMessage()(shared/src/messages.ts)only special-cases
systemandrate_limit_eventmessage types and defaultseverything else to visible, so this new event type falls through and its raw
JSON body renders directly in the chat, e.g.:
{ "type": "output", "data": { "type": "tool_progress", "uuid": "...", "parentUuid": "...", "isSidechain": true, "tool_use_id": "...", "elapsed_time_seconds": 32, "message": "Bash tool running for 32s..." } }Solution
Same pattern as the existing
rate_limit_eventfilter (#423,fix: filter rate_limit_event from Claude Remote/Local chat paths): add an explicittool_progressdeny branch toisClaudeChatVisibleMessage(). Because thisfunction is the single gate consumed by the CLI local launcher, the CLI
chat-visibility re-export, and both web
normalizeAgent.tscall sites, thefix propagates to local- and remote-mode sessions alike without touching any
of those call sites.
Screenshots
The Task subagent card renders identically
runningin both (spinner + elapsed timer) — the only difference is the raw JSON heartbeat text underneath it.Tests
hides tool_progress heartbeat messages from chat deliverynext tothe existing
rate_limit_eventcase incli/src/claude/utils/chatVisibility.test.ts.bun run test(root): cli 1364 tests / hub 499 tests / web 1297 tests /shared 114 tests, all passing.
bun typecheck: clean across cli/web/hub./clinamespace + Playwright):injected an assistant message with a running Task (subagent) tool_use block
(no
tool_resultyet, so the ToolCard renders in itsrunningstate — thespinner + elapsed timer) followed by a
tool_progressheartbeat for thatsubagent's sidechain, once with the fix reverted and once with the fix
applied. Screenshots above reproduce the shape of the original bug report
(a running subagent tool card with raw JSON leaking underneath it) — the
Task card renders identically running in both captures, and the only
difference between before/after is that the heartbeat JSON text underneath
it disappears once the fix is applied.