diff --git a/src/renderer/src/components/status-bar/ResourceUsageStatusSegment.tsx b/src/renderer/src/components/status-bar/ResourceUsageStatusSegment.tsx
index 635429b091b..2908994204b 100644
--- a/src/renderer/src/components/status-bar/ResourceUsageStatusSegment.tsx
+++ b/src/renderer/src/components/status-bar/ResourceUsageStatusSegment.tsx
@@ -701,15 +701,15 @@ export function ResourceUsageStatusSegment({
}
void fetchSnapshot()
void refreshSessions()
+ // Why: sessions already have an always-on poll in the effect below; only
+ // the memory snapshot is gated on the popover being open. Stacking a
+ // second sessions interval here doubled IPC traffic while the popover
+ // was open.
const memTimer = window.setInterval(() => {
void fetchSnapshot()
}, POLL_MS)
- const sessTimer = window.setInterval(() => {
- void refreshSessions()
- }, SESSIONS_POLL_MS)
return () => {
window.clearInterval(memTimer)
- window.clearInterval(sessTimer)
}
}, [open, fetchSnapshot, refreshSessions])
@@ -824,7 +824,12 @@ export function ResourceUsageStatusSegment({
}
}, [snapshot])
- const daemonUnreachable = sessionsError && memorySnapshotError !== null
+ // Why: memorySnapshotError is null both for "last fetch succeeded" and
+ // "never fetched". When the segment is mounted but the popover hasn't
+ // been opened, fetchMemorySnapshot has never run, so a sessions IPC
+ // failure on the always-on poll would otherwise be silent. Treat the
+ // absence of any snapshot plus a sessions error as unreachable too.
+ const daemonUnreachable = sessionsError && (memorySnapshotError !== null || snapshot === null)
// Why: a partial failure where the sessions IPC fails but the snapshot
// IPC still works was silently invisible after the merge — the old
// SessionsTabPanel surfaced it as "Terminal sessions unavailable". Show
@@ -911,10 +916,17 @@ export function ResourceUsageStatusSegment({
// bulk "Kill orphan terminals" button. Bound sessions still confirm.
if (!session.bound) {
setSessions((prev) => prev.filter((s) => s.id !== session.sessionId))
- void window.api.pty.kill(session.sessionId).catch(() => {
- /* already dead */
- })
- void refreshSessions()
+ // Why: await the kill before refreshing — otherwise the optimistic
+ // removal races a refresh that re-reads the daemon list before the
+ // kill lands and re-adds the row that was just removed.
+ void (async () => {
+ try {
+ await window.api.pty.kill(session.sessionId)
+ } catch {
+ /* already dead */
+ }
+ await refreshSessions()
+ })()
return
}
setKillConfirm(session)
@@ -1268,62 +1280,66 @@ export function ResourceUsageStatusSegment({
)}
-
-
)