@@ -62,6 +62,18 @@ const BUNDLE_REF_PREFIX = "refs/mux-bundle/";
6262/** Small backoff for concurrent writers healing the same shared base repo config. */
6363const BASE_REPO_CONFIG_LOCK_RETRY_DELAYS_MS = [ 50 , 100 , 200 ] ;
6464
65+ const sharedProjectLayouts = new Map < string , RemoteProjectLayout > ( ) ;
66+
67+ function getProjectLayoutCacheKey ( config : SSHRuntimeConfig , projectPath : string ) : string {
68+ return [
69+ config . host ,
70+ config . port ?. toString ( ) ?? "22" ,
71+ config . identityFile ?? "default" ,
72+ config . srcBaseDir ,
73+ projectPath ,
74+ ] . join ( ":" ) ;
75+ }
76+
6577function isGitConfigLockConflict ( message : string ) : boolean {
6678 return / c o u l d n o t l o c k c o n f i g f i l e / i. test ( message ) ;
6779}
@@ -166,6 +178,10 @@ export function computeBaseRepoPath(srcBaseDir: string, projectPath: string): st
166178 *
167179 * Extends RemoteRuntime for shared exec/file operations.
168180 */
181+ export function clearSharedProjectLayoutCache ( ) : void {
182+ sharedProjectLayouts . clear ( ) ;
183+ }
184+
169185export class SSHRuntime extends RemoteRuntime {
170186 private readonly config : SSHRuntimeConfig ;
171187 private readonly transport : SSHTransport ;
@@ -195,7 +211,7 @@ export class SSHRuntime extends RemoteRuntime {
195211 this . currentWorkspacePath = options ?. workspacePath ;
196212
197213 if ( options ?. projectPath && options . workspacePath ) {
198- this . projectLayouts . set (
214+ this . cacheProjectLayout (
199215 options . projectPath ,
200216 buildRemoteProjectLayout (
201217 this . config . srcBaseDir ,
@@ -250,15 +266,31 @@ export class SSHRuntime extends RemoteRuntime {
250266 return buildRemoteProjectLayout ( this . config . srcBaseDir , projectPath ) ;
251267 }
252268
269+ private getCachedProjectLayout ( projectPath : string ) : RemoteProjectLayout | undefined {
270+ return (
271+ this . projectLayouts . get ( projectPath ) ??
272+ sharedProjectLayouts . get ( getProjectLayoutCacheKey ( this . config , projectPath ) )
273+ ) ;
274+ }
275+
276+ private cacheProjectLayout (
277+ projectPath : string ,
278+ layout : RemoteProjectLayout
279+ ) : RemoteProjectLayout {
280+ this . projectLayouts . set ( projectPath , layout ) ;
281+ sharedProjectLayouts . set ( getProjectLayoutCacheKey ( this . config , projectPath ) , layout ) ;
282+ return layout ;
283+ }
284+
253285 private getPreferredProjectLayout ( projectPath : string ) : RemoteProjectLayout {
254- return this . projectLayouts . get ( projectPath ) ?? this . getDefaultProjectLayout ( projectPath ) ;
286+ return this . getCachedProjectLayout ( projectPath ) ?? this . getDefaultProjectLayout ( projectPath ) ;
255287 }
256288
257289 private async resolveProjectLayout (
258290 projectPath : string ,
259291 workspaceName ?: string
260292 ) : Promise < RemoteProjectLayout > {
261- const cached = this . projectLayouts . get ( projectPath ) ;
293+ const cached = this . getCachedProjectLayout ( projectPath ) ;
262294 if ( cached ) {
263295 return cached ;
264296 }
@@ -286,11 +318,9 @@ export class SSHRuntime extends RemoteRuntime {
286318 timeout : 10 ,
287319 } ) ;
288320 const layout = detection . stdout . trim ( ) === "legacy" ? legacyLayout : preferredLayout ;
289- this . projectLayouts . set ( projectPath , layout ) ;
290- return layout ;
321+ return this . cacheProjectLayout ( projectPath , layout ) ;
291322 } catch {
292- this . projectLayouts . set ( projectPath , preferredLayout ) ;
293- return preferredLayout ;
323+ return this . cacheProjectLayout ( projectPath , preferredLayout ) ;
294324 }
295325 }
296326
@@ -435,12 +465,7 @@ export class SSHRuntime extends RemoteRuntime {
435465 return this . currentWorkspacePath ;
436466 }
437467
438- const cachedLayout = this . projectLayouts . get ( projectPath ) ;
439- if ( cachedLayout ) {
440- return getRemoteWorkspacePath ( cachedLayout , workspaceName ) ;
441- }
442-
443- return getRemoteWorkspacePath ( this . getDefaultProjectLayout ( projectPath ) , workspaceName ) ;
468+ return getRemoteWorkspacePath ( this . getPreferredProjectLayout ( projectPath ) , workspaceName ) ;
444469 }
445470
446471 /**
0 commit comments