Two latent bugs kept the "Processing with Claude Code..." timer ticking
after the agent had already answered:
1. The A2A_RESPONSE store handler wrote into agentMessages[workspaceId]
(no prefix) but ChatTab's "clear sending" effect subscribed to
agentMessages["a2a:" + workspaceId]. Keys never matched — the effect
was dead code from day one. Removed the dead subscription and moved
the setSending(false) into the pendingAgentMsgs effect so any reply
delivered via a WS push (Claude Code SDK, Hermes's
send_message_to_user) also closes the spinner.
2. Added an activity-log fallback: when the platform emits a successful
a2a_receive ACTIVITY_LOGGED for this workspace, clear sending and
stop the timer. That covers the "runtime answered but we never saw
the store message" case Claude Code exhibited tonight — the HTTP
request can stay in flight while the SDK already pushed its reply.
Symmetric a2a_receive error path also clears sending and surfaces the
error message, so a runtime-side failure no longer hangs the UI.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>