fix(web): address eighth-pass bugbot review issues

- useSessionEvents: mux-active SSE cleanup now also resets
  pendingMembershipKeyRef and refreshingRef so the aborted fetch's
  .finally() handler cannot reschedule after unmount
- DirectTerminal: add distinct "Disconnected" label and error-coloured
  dot for muxStatus "disconnected" (WebSocket constructor failure with
  no reconnect), instead of the misleading "Connecting…" shown for
  transient states

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Gaurav Bhola 2026-04-02 20:22:28 -07:00
parent 2da6906be8
commit b04137f6bc
2 changed files with 13 additions and 4 deletions

View File

@ -482,17 +482,23 @@ export function DirectTerminal({
const statusDotClass =
displayStatus === "connected"
? "bg-[var(--color-status-ready)]"
: displayStatus === "error"
: displayStatus === "error" || displayStatus === "disconnected"
? "bg-[var(--color-status-error)]"
: "bg-[var(--color-status-attention)] animate-[pulse_1.5s_ease-in-out_infinite]";
const statusText =
displayStatus === "connected" ? "Connected" : displayStatus === "error" ? (error ?? "Error") : "Connecting…";
displayStatus === "connected"
? "Connected"
: displayStatus === "error"
? (error ?? "Error")
: displayStatus === "disconnected"
? "Disconnected"
: "Connecting…";
const statusTextColor =
displayStatus === "connected"
? "text-[var(--color-status-ready)]"
: displayStatus === "error"
: displayStatus === "error" || displayStatus === "disconnected"
? "text-[var(--color-status-error)]"
: "text-[var(--color-text-tertiary)]";

View File

@ -233,11 +233,14 @@ export function useSessionEvents(
if (muxActive) {
dispatch({ type: "setConnection", status: "connected" });
return () => {
// Clear any pending refresh timer so it doesn't fire after unmount
// Clear timer and reset all refresh state so the aborted fetch's
// .finally() handler doesn't reschedule after unmount.
if (refreshTimerRef.current) {
clearTimeout(refreshTimerRef.current);
refreshTimerRef.current = null;
}
pendingMembershipKeyRef.current = null;
refreshingRef.current = false;
activeRefreshControllerRef.current?.abort();
activeRefreshControllerRef.current = null;
};