[Init] Initial commit - NetMesh terminal manager
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
This commit is contained in:
113
application/state/sftp/browseSessionLifecycle.ts
Normal file
113
application/state/sftp/browseSessionLifecycle.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Browse vs transfer session lifecycle helpers.
|
||||
*
|
||||
* FileZilla model: a *closed* terminal SFTP side panel can soft-close its browse
|
||||
* SFTP channels while bulk transfers keep dedicated pool connections (and any
|
||||
* leased browse sessions held by in-flight streams). Switching to another side
|
||||
* panel tool (History / System / …) must keep browse warm — the owner stays
|
||||
* mounted for instant switch-back, and parking would force reconnect + reload.
|
||||
*/
|
||||
|
||||
export function isBrowseSessionInteractive(params: {
|
||||
surfaceVisible: boolean;
|
||||
/**
|
||||
* Terminal side panel still open for this owner (another tool may be focused).
|
||||
* Keeps browse sessions alive across tool switches without treating that as a
|
||||
* full panel dismiss.
|
||||
*/
|
||||
ownerPanelOpen?: boolean;
|
||||
hasOwnedEditorTab: boolean;
|
||||
/** External editor temp files (Notepad++ etc.) still need the browse session. */
|
||||
hasActiveExternalEdit?: boolean;
|
||||
}): boolean {
|
||||
return params.surfaceVisible
|
||||
|| !!params.ownerPanelOpen
|
||||
|| params.hasOwnedEditorTab
|
||||
|| !!params.hasActiveExternalEdit;
|
||||
}
|
||||
|
||||
export function listRemoteBrowseConnectionIds(
|
||||
tabs: ReadonlyArray<{
|
||||
connection: { id: string; isLocal: boolean } | null;
|
||||
}>,
|
||||
): string[] {
|
||||
const ids = new Set<string>();
|
||||
for (const tab of tabs) {
|
||||
const connection = tab.connection;
|
||||
if (!connection || connection.isLocal) continue;
|
||||
ids.add(connection.id);
|
||||
}
|
||||
return [...ids];
|
||||
}
|
||||
|
||||
/** Stable SFTP pane tab ids for editor ownership across browse reconnects. */
|
||||
export function listRemoteBrowseSftpTabIds(
|
||||
tabs: ReadonlyArray<{
|
||||
id: string;
|
||||
connection: { id: string; isLocal: boolean } | null;
|
||||
}>,
|
||||
): string[] {
|
||||
const ids = new Set<string>();
|
||||
for (const tab of tabs) {
|
||||
const connection = tab.connection;
|
||||
if (!connection || connection.isLocal) continue;
|
||||
ids.add(tab.id);
|
||||
}
|
||||
return [...ids];
|
||||
}
|
||||
|
||||
export function shouldParkBrowseSessions(params: {
|
||||
interactive: boolean;
|
||||
/** True after we already soft-closed browse while the owner stayed mounted. */
|
||||
browseParked: boolean;
|
||||
/** Defer park while unfinished transfers may still use browse sessions pre-lease. */
|
||||
activeTransfersCount?: number;
|
||||
/**
|
||||
* Defer park while an external editor still holds a downloaded temp file.
|
||||
* Parking calls closeSftp, which deletes those temps and breaks save/sync.
|
||||
*/
|
||||
activeExternalEditCount?: number;
|
||||
}): boolean {
|
||||
if (params.activeTransfersCount && params.activeTransfersCount > 0) return false;
|
||||
if (params.activeExternalEditCount && params.activeExternalEditCount > 0) return false;
|
||||
return !params.interactive && !params.browseParked;
|
||||
}
|
||||
|
||||
export function shouldRestoreBrowseSessions(params: {
|
||||
interactive: boolean;
|
||||
browseParked: boolean;
|
||||
}): boolean {
|
||||
return params.interactive && params.browseParked;
|
||||
}
|
||||
|
||||
export interface BrowseSessionEntry {
|
||||
connectionId: string;
|
||||
sftpId: string;
|
||||
}
|
||||
|
||||
/** Snapshot + clear the connectionId→sftpId map used by the file browser. */
|
||||
export function takeBrowseSessionsForClose(
|
||||
sessions: Map<string, string>,
|
||||
): BrowseSessionEntry[] {
|
||||
const entries = [...sessions.entries()].map(([connectionId, sftpId]) => ({
|
||||
connectionId,
|
||||
sftpId,
|
||||
}));
|
||||
sessions.clear();
|
||||
return entries;
|
||||
}
|
||||
|
||||
export function listRemoteConnectionIdsForRestore(params: {
|
||||
leftTabs: ReadonlyArray<{ connection: { id: string; isLocal: boolean } | null }>;
|
||||
rightTabs: ReadonlyArray<{ connection: { id: string; isLocal: boolean } | null }>;
|
||||
liveSessionConnectionIds: ReadonlySet<string>;
|
||||
}): string[] {
|
||||
const ids = new Set<string>();
|
||||
for (const tab of [...params.leftTabs, ...params.rightTabs]) {
|
||||
const connection = tab.connection;
|
||||
if (!connection || connection.isLocal) continue;
|
||||
if (params.liveSessionConnectionIds.has(connection.id)) continue;
|
||||
ids.add(connection.id);
|
||||
}
|
||||
return [...ids];
|
||||
}
|
||||
Reference in New Issue
Block a user