fix(tasks): clear running status when agent session exits#2377
fix(tasks): clear running status when agent session exits#2377janburzinski wants to merge 1 commit into
Conversation
Greptile SummaryThis PR fixes a UX bug where the sidebar task "running" indicator would stay stuck after an agent session was detached or forcibly closed. It emits a new
Confidence Score: 5/5Safe to merge — the exit event is correctly guarded to avoid double-emits across all code paths, and clearWorking is a no-op for statuses other than working and awaiting-input, limiting blast radius. The change is narrow and well-contained: two symmetric provider files gain guarded event emissions, and the renderer-side handler only resets status when it is actively running. The tmux/non-tmux guards correctly prevent duplicate events in every call path (detach→stop, destroyAll, detachAll). Tests cover the two critical new paths. No files require special attention. Both provider implementations are symmetric and their new event-emission paths are covered by the added tests.
|
| Filename | Overview |
|---|---|
| src/main/core/conversations/impl/local-conversation.ts | Adds agentSessionExitedChannel emission across detachSession, stopSession, destroyAll, and detachAll; tmux vs non-tmux guards prevent double-emits; logic is symmetric with ssh-conversation.ts. |
| src/main/core/conversations/impl/ssh-conversation.ts | Mirror of local-conversation.ts changes for the SSH provider; identical structure and guards. |
| src/renderer/features/tasks/conversations/conversation-manager.test.ts | Adds a proper IPC event mock that supports handler registration/deregistration, plus a test verifying taskStatus clears to null when the session-exited event fires. |
| src/main/core/conversations/impl/conversation-provider-respawn.test.ts | Adds mockClear between detachSession and stopSession and asserts the exit event is emitted on stopSession for the tmux/respawn path. |
Sequence Diagram
sequenceDiagram
participant User
participant Provider as Local/SshConversationProvider
participant Events as IPC Events
participant Renderer as ConversationManagerStore
User->>Provider: detachSession(conversationId)
Provider->>Provider: detachPty() returns bool
alt non-tmux and PTY was found
Provider->>Events: "emit(agentSessionExitedChannel, {conversationId, taskId})"
Events->>Renderer: listenToSessionExited handler
Renderer->>Renderer: "conversationStore.clearWorking() → status = idle"
end
User->>Provider: stopSession(conversationId)
Provider->>Provider: supervisor.stop() / sessions.get()
alt PTY found OR (tmux and wasKnownSession)
Provider->>Events: "emit(agentSessionExitedChannel, {conversationId, taskId})"
Events->>Renderer: listenToSessionExited handler
Renderer->>Renderer: "conversationStore.clearWorking() → status = idle"
end
User->>Provider: destroyAll()
Provider->>Provider: detachAll() emits per session if non-tmux
alt tmux mode
Provider->>Events: emit(agentSessionExitedChannel) per knownSessionId
Events->>Renderer: listenToSessionExited handler
Renderer->>Renderer: "conversationStore.clearWorking() → status = idle"
end
Reviews (1): Last reviewed commit: "fix(tasks): clear running status when ag..." | Re-trigger Greptile
Description
Screenshot/Recording (if applicable)
https://streamable.com/eaqqlm
Checklist
messages and, when possible, the PR title