diff --git a/src/main/persistence.ts b/src/main/persistence.ts index 213b0a600b6..9517e6ba9f1 100644 --- a/src/main/persistence.ts +++ b/src/main/persistence.ts @@ -6590,25 +6590,6 @@ export class Store { return normalizeExecutionHostId(hostId) ?? LOCAL_EXECUTION_HOST_ID } - /** - * Re-run the partition hoist against current state. - * - * Why this is not construction-only: `ssh:` is a LIVE plane. A tab the CLI or a headless - * surface creates mid-session lands there, `local` never learns of it, and a reattach then - * refuses it as `noTab` — the shell runs on unbound and its tab stays invisible until the app - * restarts. Re-hoisting on that refusal closes the window without polling. - */ - hoistSshPartitionsNow(): boolean { - const changed = hoistSshPartitionsIntoLocalSession( - this.state, - this.state.workspaceSessionsByHostId - ) - if (changed) { - this.scheduleSave() - } - return changed - } - /** Read once, immediately after a refused `persistPtyBinding`. Clearing on read keeps a stale * reason from being attributed to a later call that never set one. */ consumePtyBindingRefusalReason(): PtyBindingRefusalReason | undefined { diff --git a/src/main/ssh-partition-upgrade-tab-loss.test.ts b/src/main/ssh-partition-upgrade-tab-loss.test.ts index ac86475d3fc..8eeb96a7e55 100644 --- a/src/main/ssh-partition-upgrade-tab-loss.test.ts +++ b/src/main/ssh-partition-upgrade-tab-loss.test.ts @@ -485,40 +485,4 @@ describe('an SSH pane whose membership was persisted into the ssh partition', () 'a local-only layout edit reached through into the ssh partition' ).toBe(PTY) }) - - // `ssh:` is a LIVE plane: the CLI and headless surfaces still write it. A tab created - // there mid-session is not in `local`, so a reattach refuses it as noTab and its shell runs on - // unbound. Re-hoisting on demand closes that window without waiting for a restart. - it('folds in a tab the partition gained mid-session, without a restart', async () => { - const before = await createStore() - before.setWorkspaceSession(paneSession() as never, SSH_PARTITION) - before.flushOrThrow() - stripHoistMarker() - - const store = await reopenStore() - expect(store.getWorkspaceSession().tabsByWorktree?.[WORKTREE] ?? []).toHaveLength(1) - - // The CLI adds a pane to the partition while the app is running. - const grown = paneSession() - grown.tabsByWorktree[WORKTREE] = [ - ...grown.tabsByWorktree[WORKTREE], - { ...grown.tabsByWorktree[WORKTREE][0], id: 'tab-cli' } - ] - grown.terminalLayoutsByTabId = { - ...grown.terminalLayoutsByTabId, - 'tab-cli': { - root: { type: 'leaf' as const, leafId: LEAF_TWO }, - activeLeafId: LEAF_TWO, - expandedLeafId: null, - ptyIdsByLeafId: { [LEAF_TWO]: PTY } - } - } as typeof grown.terminalLayoutsByTabId - store.setWorkspaceSession(grown as never, SSH_PARTITION) - - expect(store.hoistSshPartitionsNow(), 'the on-demand hoist reported no change').toBe(true) - expect( - (store.getWorkspaceSession().tabsByWorktree?.[WORKTREE] ?? []).map((tab) => tab.id).sort(), - 'a tab the partition gained mid-session stayed invisible until restart' - ).toEqual(['tab-1', 'tab-cli']) - }) }) diff --git a/src/main/ssh/ssh-relay-session.ts b/src/main/ssh/ssh-relay-session.ts index bc1e3b98d0c..a292184352a 100644 --- a/src/main/ssh/ssh-relay-session.ts +++ b/src/main/ssh/ssh-relay-session.ts @@ -2618,21 +2618,6 @@ export class SshRelaySession { } catch (error) { console.error('[ssh-relay-session] Failed to persist reconnect incarnation:', error) } - if (bind?.bound === false && bind.refusalReason === 'noTab') { - // The partition is a live plane, so a tab created there mid-session is not in `local` yet. - // Fold it in and try once more before concluding no pane owns this shell. - if (this.store?.hoistSshPartitionsNow()) { - bind = bindPaneShell({ - store: this.store, - worktreeId: lease.worktreeId, - tabId, - leafId: lease.leafId, - ptyId: appPtyId, - mayCreate: false, - ...(incarnationId ? { incarnationId } : {}) - }) - } - } if (bind?.bound === false && bind.refusalReason === 'noTab') { // No durable tab owns this leaf, so there is nothing to publish it against — registering // would announce a pane that does not exist. Unresolved, not dead: the shell keeps running