Skip to content

Commit 8754f22

Browse files
committed
fix(web): stop cursor pulse when Claude finishes a turn
Add isThinking state to track whether Claude is actively generating. Set to false on result events (turn complete), true on assistant events and when user sends a message. The blinking cursor now uses isRunning && isThinking, so it stops pulsing when Claude is waiting for user input instead of spinning indefinitely.
1 parent 46e0c1e commit 8754f22

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

apps/web/src/features/session/ContainerSession.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export default function ContainerSession({
5353
const [stopping, setStopping] = useState(false)
5454
const [userInput, setUserInput] = useState('')
5555
const [sending, setSending] = useState(false)
56+
const [isThinking, setIsThinking] = useState(true)
5657

5758
const msgIdRef = useRef(0)
5859
const sseOffsetRef = useRef(0)
@@ -226,6 +227,17 @@ export default function ContainerSession({
226227
if (event.lastEventId) {
227228
sseOffsetRef.current = parseInt(event.lastEventId, 10) || sseOffsetRef.current
228229
}
230+
231+
// Track turn state: cursor pulses while Claude generates,
232+
// stops when a result event signals turn complete.
233+
try {
234+
const raw = JSON.parse(event.data as string) as { type?: string }
235+
if (raw.type === 'assistant') setIsThinking(true)
236+
else if (raw.type === 'result') setIsThinking(false)
237+
} catch {
238+
// ignore — thinking state is best-effort
239+
}
240+
229241
const parsed = parseStreamMessage(event.data as string)
230242
if (parsed) {
231243
appendMessage(parsed)
@@ -252,6 +264,7 @@ export default function ContainerSession({
252264
source.close()
253265
eventSourceRef.current = null
254266
setStatus('completed')
267+
setIsThinking(false)
255268
try {
256269
const parsed = JSON.parse(event.data as string) as { message?: string }
257270
appendStatus(parsed.message ?? 'Session completed.')
@@ -323,6 +336,7 @@ export default function ContainerSession({
323336
const content = userInput.trim()
324337
setSending(true)
325338
setUserInput('')
339+
setIsThinking(true)
326340
// Show user's input as a user message in the conversation
327341
appendMessage({
328342
role: 'user',
@@ -455,7 +469,7 @@ export default function ContainerSession({
455469

456470
{/* Conversation output */}
457471
<div className="flex-1 min-h-0">
458-
<ConversationOutput messages={messages} isRunning={isRunning} />
472+
<ConversationOutput messages={messages} isRunning={isRunning && isThinking} />
459473
</div>
460474

461475
{/* Message input */}

0 commit comments

Comments
 (0)