fix(ui): a stream that went quiet reconnects, the rail says so, the panel opens on the master

A phone that slept brings back an SSE socket that never errored and never
delivers: the panel read as live for hours while showing nothing new. Every
chunk now marks the connection alive and a watchdog drops the socket after
40s of silence - twice the server's keepalive - so the loop reconnects.
Each attempt gets its own controller, which is what lets the watchdog (and
a manual refresh) end one connection without ending the loop.

The connection is admitted in one dot beside the rail's search box, tapped
to reconnect at once rather than waiting out the backoff - the pill that
used to say this was dropped in the redesign and the panel had no way to
own up to being stale.

With nothing picked, the shell lands on the freshest open master instead of
a prompt to pick something: what a phone wants when the panel opens. An
explicit pick, and following the active note, still win.
This commit is contained in:
hh committed 2026-09-05 00:20:03 +02:00
1 parent 8019c76e53
commit 421248b0ad
6 files changed
+176 -11

No files matched your search

+3 -2
View File
@@ -148,7 +148,8 @@ export class ApiClient {
async stream(
path: string,
onEvent: (event: BusEvent) => void,
signal: AbortSignal
signal: AbortSignal,
onActivity?: () => void
): Promise<void> {
const response = await fetch(this.url(path), {
headers: this.headers({ Accept: "text/event-stream" }),
@@ -162,7 +163,7 @@ export class ApiClient {
payload
);
}
await readSse(response, onEvent, signal);
await readSse(response, onEvent, signal, onActivity);
}
agents(): Promise<AgentsResponse> {