fix: persist local panels in disconnected remote workspaces - #268
Merged
Conversation
A workspace the user disconnects from its remote host but keeps using with local shells was silently dropped from every session snapshot for the rest of its life -- three live terminals lost on relaunch with no warning (release 0.4.218 incident). remoteConfiguration intentionally survives a user-initiated disconnect (the default and the sidebar's disconnect action both pass clearConfiguration: false) so reconnectRemoteConnection() has something to reconnect to. That made isRemoteWorkspace (config presence) a bad proxy for "this workspace's panels currently live on a remote host" -- a disconnected-but-configured workspace is a local workspace again for every practical purpose. Added isLiveRemoteWorkspace (config present AND connection state != disconnected) and switched session persistence, and the matching telemetry-routing branches in TerminalController+Telemetry, to it. Also logs a session.snapshot diagnostics line for every workspace still skipped (a genuinely live remote workspace), so the gap can never be silent again.
Member
Author
|
Residual edge worth tracking separately (not blocking): |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Disconnect a remote workspace from the sidebar, keep using it with local shells, and every terminal in it silently vanished from session persistence -- gone at the next restart, with no warning. Three live local terminals were lost this way in a real incident on release 0.4.218: the workspace was absent from both the autosave and the clean-quit snapshot, and there was nothing in the diagnostics log to explain why.
The root cause:
remoteConfigurationintentionally survives a user-initiated disconnect (the sidebar's disconnect action passesclearConfiguration: falseon purpose, so Reconnect keeps working), but the session-snapshot filter excluded any workspace withremoteConfiguration != nil-- stale config presence, not whether the workspace is actually still live remote right now.Summary
Workspace.isLiveRemoteWorkspace(isRemoteWorkspace && remoteConnectionState != .disconnected) and switchedTabManager.sessionSnapshotto it, so a disconnected-but-configured workspace persists its local panels like any other workspace.remoteConfigurationon disconnect instead (simplest fix): rejected --reconnectRemoteConnection()and the socketworkspace.remote_reconnectpath bothguard let remoteConfigurationbefore reconnecting, so clearing it on disconnect would permanently break Reconnect.session.snapshot skipped workspace=<id> reason=remote panels=<n>to the always-on diagnostics log (~/Library/Logs/Programa/diagnostics.log), so this class of gap is never silent again.TerminalController+Telemetry's TTY-report/port-kick routing had the same stale-flag bug (a disconnected-but-configured workspace's local panels stopped getting local port-scanning/dev-server detection, since telemetry kept routing to an inert remote path) -- switched those 4 branches toisLiveRemoteWorkspacetoo.isRemoteWorkspacecall sites (sidebar Reconnect/Disconnect menu state, browser proxy website-data-store routing, git-metadata-polling exclusion) untouched -- those gate "has a remote destination configured" facts, not the live-session distinction this bug is about.Known residual gap (disclosed, not fixed here): a workspace that is still actively connected but also contains local panels (possible when a split is created without an auto-connect startup command) still has those local panels excluded from persistence, same as before. It's no longer silent -- the new diagnostics line fires for it too -- but a full fix needs panel-level filtering in the layout snapshot, which is a larger, separate change.
Test Plan
xcodebuild -project GhosttyTabs.xcodeproj -scheme programa -configuration Debug -destination 'platform=macOS' -derivedDataPath /tmp/programa-remotefix build-> BUILD SUCCEEDED-only-testing:programaTests/WorkspaceRemoteConnectionTests-> 41/41 passed-only-testing:programaTests/TabManagerSessionSnapshotTests-> 3/3 passed (existing exclusion test updated to simulate an actually-connected workspace, since it previously relied on the buggy "config present = excluded" behavior)-only-testing:programaTests/SessionPersistenceTests-> 62/62 passed-only-testing:programaTests/TerminalControllerSocketSecurityTests-> 11/11 passed