@@ -256,10 +256,10 @@ export async function restartMobilePreview(
256256 } ) ;
257257}
258258
259- // First import run only: clone the public GitHub repo over the empty workspace,
260- // drop the one-shot marker, best-effort install, and hand control to the agent
261- // without auto-starting a dev server (framework/port are unknowable). Failure
262- // throws repo_import_failed, which rides the existing run() failure path.
259+ // First import run only: retain uploads, clone the public GitHub repo through a
260+ // private staging directory, drop the one-shot marker, best-effort install, and
261+ // hand control to the agent without auto-starting a dev server (framework/port
262+ // are unknowable). Failure throws repo_import_failed through the run failure path.
263263async function importRepoWorkspace (
264264 options : WorkspaceOptions & { repoUrl : string } ,
265265) : Promise < { agentContextNote : string } > {
@@ -273,9 +273,11 @@ async function importRepoWorkspace(
273273 }
274274 logger . info ( "repo_import_started" , { repoHost : repoRef . host , repoPath : repoRef . path } ) ;
275275 setRunStage ( `Cloning ${ repoRef . path } .` ) ;
276- await resetAppBuilderDirectory ( sandbox , workspace . dir ) ;
276+ await resetTemplateAppBuilderDirectory ( sandbox , workspace . dir ) ;
277277 throwIfRunCanceled ( options . abortSignal ) ;
278- await cloneRepoOrThrow ( { dir : workspace . dir , env, input, logger, repoRef, repoUrl, sandbox } ) ;
278+ const cloneDir = `${ workspace . dir } /.cheatcode-import-${ input . runId ?? crypto . randomUUID ( ) } ` ;
279+ await cloneRepoOrThrow ( { dir : cloneDir , env, input, logger, repoRef, repoUrl, sandbox } ) ;
280+ await promoteImportedRepo ( sandbox , cloneDir , workspace . dir ) ;
279281 throwIfRunCanceled ( options . abortSignal ) ;
280282 await markImportedWorkspace ( sandbox , workspace . dir ) ;
281283 const installRan = await installImportedDependencies ( sandbox , logger , workspace . dir ) ;
@@ -291,6 +293,29 @@ async function importRepoWorkspace(
291293 return { agentContextNote : importedContextNote ( workspace , repoUrl ) } ;
292294}
293295
296+ async function promoteImportedRepo (
297+ sandbox : ProjectSandboxStub ,
298+ cloneDir : string ,
299+ workspaceDir : string ,
300+ ) : Promise < void > {
301+ await executeShellExec (
302+ { command : [ "rm" , "-rf" , `${ cloneDir } /uploads` ] , cwd : "/workspace" , timeoutMs : 120_000 } ,
303+ { sandbox } ,
304+ ) ;
305+ await executeShellExec (
306+ {
307+ command : [ "cp" , "-a" , `${ cloneDir } /.` , `${ workspaceDir } /` ] ,
308+ cwd : "/workspace" ,
309+ timeoutMs : 120_000 ,
310+ } ,
311+ { sandbox } ,
312+ ) ;
313+ await executeShellExec (
314+ { command : [ "rm" , "-rf" , cloneDir ] , cwd : "/workspace" , timeoutMs : 120_000 } ,
315+ { sandbox } ,
316+ ) ;
317+ }
318+
294319// Every follow-up run of an imported project: re-install best-effort, but NEVER
295320// reset, re-clone, or auto-start the template dev server (prior agent
296321// edits must survive).
@@ -620,13 +645,6 @@ async function hasInstalledAppBuilderDependencies(
620645 return result . success ;
621646}
622647
623- async function resetAppBuilderDirectory ( sandbox : ProjectSandboxStub , dir : string ) : Promise < void > {
624- await executeShellExec (
625- { command : [ "rm" , "-rf" , dir ] , cwd : "/workspace" , timeoutMs : 120_000 } ,
626- { sandbox } ,
627- ) ;
628- }
629-
630648async function resetTemplateAppBuilderDirectory (
631649 sandbox : ProjectSandboxStub ,
632650 dir : string ,
0 commit comments