Skip to content

fix(daemon): report a connected extension that cannot run commands - #319

Merged
iuyo5678 merged 5 commits into
mainfrom
fix/extension-reconnect-status
Sep 29, 2026
Merged

iuyo5678 merged 5 commits into
mainfrom
fix/extension-reconnect-status

Conversation

@iuyo5678

Copy link
Copy Markdown
Collaborator

Problem

A browser can show as connected in the extension popup, bsk doctor, and bsk browsers while session start and tool calls wait until they time out. Reconnecting replaces the daemon registration but leaves calls on the old socket blocked. A socket that stays open and stops sending frames also stays registered until the existing liveness window, about 60 seconds. A browser process can answer a WebSocket ping before its service worker sends system.handshake; those connections are dropped after 5 seconds.

Change

Replacing a registration now fails that socket's in-flight calls immediately. Session start retries once on the new connection. If that connection is replaced too, the call reports that the extension is reconnecting and does not retry again. Tool calls are not retried. Clicks, key presses, wheel input, uploads, and downloads keep an unknown outcome, so a caller does not repeat a side effect that may already have reached the page. A disconnect that does not install a newer generation is unchanged.

A timed-out call marks the browser unresponsive only when no inbound frame has arrived for one heartbeat interval, 20 seconds. The registry entry and its other sessions stay. Later commands fail immediately with the same reason until any inbound frame clears the mark. Removal is still the existing liveness reaper. A shorter timeout does not mark the browser when a frame arrived inside that interval.

After upgrade the daemon sends one ping. A pong without a handshake extends the first-frame wait once, by 10 seconds. If neither a pong nor a handshake arrives, the connection still drops at 5 seconds. Ping and pong are not accepted as the handshake.

bsk doctor reports a warning and still exits successfully. bsk browsers names each unresponsive browser. The popup is unchanged, because a frozen service worker cannot repaint it. There is no new error code. Existing codes carry extension_reconnected, extension_reconnecting, or extension_unresponsive. BrowserStatusEntry.unresponsive defaults to false, so older status payloads still decode.

Related: #294

Validation

  • cargo test -p bsk-protocol: 156 passed.
  • cargo test -p bsk --lib: passed, including replacement, the single session-start retry, the 20-second silence threshold, handshake grace, and the CLI reason text.
  • Every crates/bsk-cli integration test target passed. One auto_spawn case timed out under parallel load and passed when run alone.
  • cargo fmt --all -- --check and cargo clippy --workspace --all-targets --locked -- -D warnings passed.
  • Not run against a live Chrome service worker. The handshake grace and the decision to leave the popup unchanged are covered by the daemon tests and the constraints above.

TencentXiaowei and others added 5 commits September 22, 2026 22:01
Fail in-flight calls when a browser generation is replaced, mark a silent heartbeat interval as unresponsive without dropping the socket, and allow one handshake grace after a pong.
…sive mark

Terminate a socket's pending calls when it is replaced or closed, and register
and send under the same lock so no call can reach an abandoned socket. A call
that was already dispatched keeps its unknown-outcome contract in every wait
stage, including tab borrow. Session start is no longer retried.

Only mark heartbeat-capable extensions unresponsive, after two missed
heartbeats, and never let the mark replace a cleanup failure.

The handshake pong grace moves to a separate change.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Calls that fail because the extension's socket closed now carry
`reason: extension_disconnected`, so the CLI no longer tells the user to
check protocol versions. Native input keeps its unknown-outcome reason.

Co-authored-by: Cursor <cursoragent@cursor.com>
@iuyo5678
iuyo5678 merged commit 39ebe1a into main Sep 29, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants