feat(chat): show Running code status during Bash execution#82
feat(chat): show Running code status during Bash execution#82Zhang-Henry merged 2 commits intomainfrom
Conversation
When an agent runs Bash/shell commands, the status indicator and thinking text now show "Running code" instead of generic "Thinking". Other tools (Edit, Grep, WebSearch, etc.) still show "Thinking".
Zhang-Henry
left a comment
There was a problem hiding this comment.
Code Review
Overall: Clean, small PR with clear intent. Two functional bugs should be addressed before merge.
Issues
1. [Bug] Hardcoded English string bypasses i18n
useChatRealtimeHandlers.ts lines 179-181 and 901 directly set text: 'Running code' as a literal English string, but the i18n keys status.runningCode are already defined in all 3 locales (chat.json). This means:
- Chinese users see "思考中..." → "Running code" (mixed languages)
- Korean users likewise see English
The issue is that useChatRealtimeHandlers is a hook where calling t() directly isn't straightforward. Suggested fix: instead of setting display text in the hook, set a semantic key (e.g., text: 'running_code'), then resolve it via i18n in AssistantThinkingIndicator at render time. Currently status.runningCode is defined in all 3 locale files but never referenced — it's dead code.
2. [Bug] Status text never resets after Bash execution completes
Tracing the full lifecycle:
claudeStatusis defined atuseChatSessionState.ts:94as{ text, tokens, can_interrupt } | null- Set to non-null: when
claude-status/gemini-statusmessages arrive (useChatRealtimeHandlers.ts:1134-1147) —textcomes from backend'sstatusData.message - Cleared to null:
clearLoadingIndicators()on session complete/error/abort (useChatRealtimeHandlers.ts:392-396)
The PR sets text to 'Running code' on Bash tool_use detection, but nothing resets it back. If Bash finishes and the model continues thinking (e.g., processing results before emitting text), text remains 'Running code' until either the backend pushes a new claude-status event or the session ends.
In practice this may be masked by frequent backend status pushes, but in edge cases (Bash completes → model directly outputs text without a new status push), the indicator stays stuck on "Running code".
Suggestion: reset text when a tool_result arrives or when a new text/thinking content block begins.
3. [Minor] Codex command_execution triggers on all lifecycle stages
The command_execution case (~line 793) handles all lifecycle phases (started/completed/etc.). The PR sets the status at the case entry, meaning even the completed phase triggers "Running code". Should only set on command start.
4. [Nit] Gemini coverage
PR description says "Applies to all 3 providers", but Bash detection is only added to Claude and Codex code paths. Gemini shares the claude-status/gemini-status handler but its tool_use events go through the same path as Claude (shared case), so Bash detection at line 179 should cover Gemini too — worth verifying this is actually the case.
Review ResponseAll 4 issues addressed. Here's what was done for each: 1. [Bug] i18n bypass — FixedInstead of setting display text directly in 2. [Bug] Status never resets — FixedThe override is cleared (
3. [Minor] Codex lifecycle — FixedGuarded with 4. [Nit] Gemini coverage — VerifiedConfirmed: Gemini routes through Architecture noteThe key design decision: |
Summary
Changes
useChatRealtimeHandlers.ts— DetectBash/run_shell_commandtool_use and updateclaudeStatus.textto "Running code" forClaude/Gemini; detect
command_executionfor CodexAssistantThinkingIndicator.tsx— AcceptstatusTextprop, default to i18nstatus.thinkingChatMessagesPane.tsx— ThreadstatusTextprop to indicatorChatInterface.tsx— PassclaudeStatus?.textto ChatMessagesPanestatus.thinkingandstatus.runningCodeTest plan