Files
tty7/src
l0ng-aiandl0ng-ai ce4a19ae89 fix(remote): let the supervisor's view of a link be the only one (#517)
* feat(i18n): give the strip and the switcher the words for a link that is retrying

The strip could count reconnect attempts but never say what any of them ran
into, and the switcher had no word at all for a machine between links or for
a workspace another client is holding.

* fix(remote): let the supervisor's view of a link be the only one

Four bugs met in this file's status pipeline, all of them a second opinion
about a link that the supervisor already knew better.

Take Back said it worked and did nothing (#488). Preempting a GUI client does
not drop its control link — the server only hangs up on a `dedicated` one — so
the pump's live branch marked the machine Attached and moved on, while the only
site that ever sent `WorkspaceAttach` sat in the *reconnect* path, which a live
link never reaches. The strip read Attached, `accepts_input` agreed, and every
keystroke went into a socket the far end had handed to somebody else.

So the live branch now attaches too. `reclaims_due` collects the workspaces the
far end has not been told about — the ones a Take Back is reclaiming, and any
this client has never spoken for over the link that is up now, because
`connect_blocking` brings a link up and stops there and every switcher-initiated
connect used to leave the daemon holding nothing. `attaching` keeps a reclaim
that is on the wire from being sent again four times a second, `attach_sent`
scopes "already told them" to one link, and `finish_reclaim` puts the takeover
back — with the name that came with it, which is why `reclaiming` now carries it
— when the far end refuses. While a reclaim is in flight the workspace reports
Connecting: not Attached, because it is not, and not Preempted, because the
button that would say so must not be clickable twice.

A window's own failed connect no longer outranks the supervisor (#489). It was
returned before `RemoteLinks` was consulted at all, and never compared against
the window's own machine, so a failed connect to the GPU box replaced the strip
of a window sitting happily on the build box. `resolve_status` takes both, and
`clear_window_failures_for` retires what the windows still say once the
supervisor gets through — precedence alone would not do, because the switcher
reads `ConnectFlow` directly.

And a reconnect says why (#498). `launch_attempt` set `Failed(e)` and the next
tick overwrote it back to `Reconnecting`, 250ms later, so the reason existed for
a quarter of a second. `MachineLink::last_error` outlives that. Retrying for
ever stays: this is a laptop lid closed overnight, and giving up would be worse.

* fix(switcher): draw a machine from what the supervisor knows, not from a table entry

`link_state` read this window's `connect` and then asked whether a `HostLinks`
entry existed. The pump drops that entry the moment a link dies, so a machine
being retried right now rendered identically to one nobody has ever connected
to — same grey dot, same "not connected", and, because the group body is only
expanded when the link is not Offline, its workspaces vanished from the panel
for the whole reconnect (#497).

`Link::Reconnecting` is the state that was missing, and `link_from` builds it
from `RemoteLinks::machine_status`, so the panel and the strip now read the same
source. Disconnect and the machine menu treat it as engaged: a retry in flight
is exactly what Disconnect is for.

The route `launch_attempt` could not build wrote `LinkState::Failed(e)` where
nothing the switcher read would ever find it. The group's error line now falls
back to the supervisor's failure and to `last_error`, rather than having the
supervisor write into `remote_host_errors` as well — one source, not two.

A takeover leaves the link alone, so a machine whose workspace another client is
holding drew as plain Connected with an "Open" badge on the row. It says so now,
on the header and on the row it happened to.

---------

Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>
2026-08-11 21:42:37 +08:00
..