From c2eeadd9a36dec614d1d1efc7133a03bd12f5420 Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Mon, 20 Apr 2026 21:42:04 +0300 Subject: [PATCH] fix: unstick isConnected when first connect follows a disconnect markConnected skipped onReconnect on the very first successful connect (hasConnected=false branch), but an earlier failed attempt could have already fired onDisconnect -> isConnected=false. Consumer state stayed stuck at false forever. Fire onReconnect in that case too. Repro: launch app while opencode sidecar is still warming up so the first WS attempt fails. Second attempt succeeds but isConnected stays false; user sees "Connection lost" toast on every send. --- packages/ui/src/sync/event-pipeline.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/ui/src/sync/event-pipeline.ts b/packages/ui/src/sync/event-pipeline.ts index 77f0636c..70c0d21e 100644 --- a/packages/ui/src/sync/event-pipeline.ts +++ b/packages/ui/src/sync/event-pipeline.ts @@ -245,12 +245,19 @@ export function createEventPipeline(input: EventPipelineInput) { let heartbeat: ReturnType | undefined const markConnected = () => { + const wasDisconnected = disconnected disconnected = false if (hasConnected) { onReconnect?.() return } hasConnected = true + // First successful connect, but an earlier attempt already fired onDisconnect + // (e.g. sidecar was not ready at launch). Consumer state is stuck at + // isConnected=false — fire onReconnect to unstick it. + if (wasDisconnected) { + onReconnect?.() + } } const enqueueEvent = (directory: string, payload: Event) => {