mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-23 08:02:27 +00:00
* fix(ui): resync local windows when the daemon comes back as a new process (#553) From the client's side a killed daemon is indistinguishable from one whose shells all exited at once — its DeathReporter says nothing while it shuts down, and a taskkill says nothing ever — so the window kept showing every pane with its last title, and the reconnect then pushed that dead layout back up as the new daemon's truth. On Windows a force-killed daemon can even leave the shells themselves alive but permanently unreachable. The control handshake already carries an instance id per server process, and the remote path already compared it (server_restarted); the local link never did. Now LocalLink remembers the hello instance — across invalidate(), deliberately, or the restart path's own first move would blind the comparison — and a changed instance on reconnect routes every local window through resync_after_local_daemon_change instead of on_link_up: the dead link is dropped first, then hydrate rebuilds from the machine tree and each pane comes back from its scrollback snapshot with the "new shell" banner. note_instance moves to tree_sync as the shared comparison (empty instance = server predates the field, never a restart, never overwrites), with the remote callers and their tests repointed. The restart-server action now uses the same helper instead of open-coding invalidate + resync, which also fixes it rebuilding only the current window when several local windows are open. Per the review, the title wording ("process exited" while the link was down) and the missing Respawn menu item are a separate PR: the current wording is pinned by a_dropped_link_does_not_claim_the_process_exited and changing it is its own decision. * docs(changelog): entry for the local-daemon reconnect resync (#553) * fix(ui): keep the reconnect's own link when the daemon came back new The reconnect installs the new daemon's client and then, on a changed instance, called the helper that starts by dropping it. The link the handshake had just proved good was thrown away, every window's pull went out with nothing to send it on, and the layout had to wait for the next tick to connect a second time. That is not only wasted work. `hydrate` gives the link fifteen seconds to come back and then owes the window a `Replace` — and a `Replace` is abandoned the moment the window has tabs, which in this scenario it always does: the dead ones still on screen are the whole bug. So a slow second connect turned the resync into nothing at all, silently. Split the helper: `resync_after_local_daemon_change` still invalidates first, for the restart-server path whose link really does point at a server it killed, and `resync_local_windows_from_tree` is the half the reconnect wants, with the fresh link left in place. The two note_instance tests that moved here with the function now say what tree_sync's own tests say; the one that is this module's — the slot is per host — stays. --------- Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>