fix(status): treat slash-command and bash user-role lines as synthetic#112
Merged
Conversation
Sessions could pin in Thinking ("◉ Think generating reply") forever
after `/plugin update` (and other pure-local slash commands or `!bash`
invocations). Claude Code flushes 2-3 user-role lines for these — a
`<local-command-caveat>` (isMeta:true), a `<command-name>` line, and a
`<local-command-stdout>` line — none of which prompt the model, so no
assistant reply ever arrives to clear `last_user_ts_ms`.
`is_tool_result_user_msg` only filtered tool_result block arrays and
let every string-content user line through, so the trailing local-
command line opened a thinking window that never closed.
Rename to `is_synthetic_user_msg` and additionally treat as synthetic:
- entries with `isMeta: true`
- string content starting with `<local-command-stdout|stderr|caveat>`,
`<command-name>`, or `<bash-input|stdout|stderr>`
Also skip these lines when extracting the session's initial_prompt so
the title isn't a `<command-name>/plugin...` dump.
Add regression tests for the /plugin three-line sequence and the
`!bash` `<bash-input>/<bash-stdout>` sequence.
graykode
approved these changes
May 10, 2026
Owner
graykode
left a comment
There was a problem hiding this comment.
lgtm — security clean (single-file parser refactor, no new deps/network/shell). the rename to is_synthetic_user_msg and lifting it to take the whole entry reads right since isMeta lives at the entry level, and keeping the "all blocks are tool_result" check conservative (mixed → still a real prompt) preserves the prior safety. nice catch also gating initial_prompt extraction so titles don't end up as <command-name>/plugin... or a bash stdout dump. the two regression tests exercise the exact 3-line /plugin sequence and the <bash-input>/<bash-stdout> pair from the bug report. merged main locally and cargo test is green (123/123).
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.
Sessions could pin in Thinking ("◉ Think generating reply") forever after
/plugin update(and other pure-local slash commands or!bashinvocations). Claude Code flushes 2-3 user-role lines for these — a<local-command-caveat>(isMeta:true), a<command-name>line, and a<local-command-stdout>line — none of which prompt the model, so no assistant reply ever arrives to clearlast_user_ts_ms.is_tool_result_user_msgonly filtered tool_result block arrays and let every string-content user line through, so the trailing local- command line opened a thinking window that never closed.Rename to
is_synthetic_user_msgand additionally treat as synthetic:isMeta: true<local-command-stdout|stderr|caveat>,<command-name>, or<bash-input|stdout|stderr>Also skip these lines when extracting the session's initial_prompt so the title isn't a
<command-name>/plugin...dump.Add regression tests for the /plugin three-line sequence and the
!bash<bash-input>/<bash-stdout>sequence.