@@ -357,115 +357,7 @@ export async function main() {
357357 ? getNodeMemoryArgs ( isDebugMode )
358358 : [ ] ;
359359
360- if ( ! process . env [ 'SANDBOX' ] && ! argv . isCommand ) {
361- const sandboxConfig = await loadSandboxConfig ( settings . merged , argv ) ;
362-
363- if ( sandboxConfig ) {
364- // Sandbox path: needs full config + auth before entering sandbox because
365- // the sandbox will interfere with the OAuth2 web redirect.
366- const partialConfig = await loadCliConfig (
367- settings . merged ,
368- sessionId ,
369- argv ,
370- {
371- projectHooks : settings . workspace . settings . hooks ,
372- } ,
373- ) ;
374- adminControlsListner . setConfig ( partialConfig ) ;
375-
376- let initialAuthFailed = false ;
377- if ( ! settings . merged . security . auth . useExternal ) {
378- try {
379- if (
380- partialConfig . isInteractive ( ) &&
381- settings . merged . security . auth . selectedType
382- ) {
383- const err = validateAuthMethod (
384- settings . merged . security . auth . selectedType ,
385- ) ;
386- if ( err ) {
387- throw new Error ( err ) ;
388- }
389-
390- await partialConfig . refreshAuth (
391- settings . merged . security . auth . selectedType ,
392- ) ;
393- } else if ( ! partialConfig . isInteractive ( ) ) {
394- const authType = await validateNonInteractiveAuth (
395- settings . merged . security . auth . selectedType ,
396- settings . merged . security . auth . useExternal ,
397- partialConfig ,
398- settings ,
399- ) ;
400- await partialConfig . refreshAuth ( authType ) ;
401- }
402- } catch ( err ) {
403- if ( err instanceof ValidationCancelledError ) {
404- await runExitCleanup ( ) ;
405- process . exit ( ExitCodes . SUCCESS ) ;
406- }
407-
408- if ( ! ( err instanceof ValidationRequiredError ) ) {
409- debugLogger . error ( 'Error authenticating:' , err ) ;
410- initialAuthFailed = true ;
411- }
412- }
413- }
414-
415- const remoteAdminSettings = partialConfig . getRemoteAdminSettings ( ) ;
416- if ( remoteAdminSettings ) {
417- settings . setRemoteAdminSettings ( remoteAdminSettings ) ;
418- }
419-
420- await runDeferredCommand ( settings . merged ) ;
421-
422- if ( initialAuthFailed ) {
423- await runExitCleanup ( ) ;
424- process . exit ( ExitCodes . FATAL_AUTHENTICATION_ERROR ) ;
425- }
426- let stdinData = '' ;
427- if ( ! process . stdin . isTTY ) {
428- stdinData = await readStdin ( ) ;
429- }
430-
431- // This function is a copy of the one from sandbox.ts
432- // It is moved here to decouple sandbox.ts from the CLI's argument structure.
433- const injectStdinIntoArgs = (
434- args : string [ ] ,
435- stdinData ?: string ,
436- ) : string [ ] => {
437- const finalArgs = [ ...args ] ;
438- if ( stdinData ) {
439- const promptIndex = finalArgs . findIndex (
440- ( arg ) => arg === '--prompt' || arg === '-p' ,
441- ) ;
442- if ( promptIndex > - 1 && finalArgs . length > promptIndex + 1 ) {
443- finalArgs [ promptIndex + 1 ] =
444- `${ stdinData } \n\n${ finalArgs [ promptIndex + 1 ] } ` ;
445- } else {
446- finalArgs . push ( '--prompt' , stdinData ) ;
447- }
448- }
449- return finalArgs ;
450- } ;
451-
452- const sandboxArgs = injectStdinIntoArgs ( process . argv , stdinData ) ;
453-
454- await relaunchOnExitCode ( ( ) =>
455- start_sandbox ( sandboxConfig , memoryArgs , partialConfig , sandboxArgs ) ,
456- ) ;
457- await runExitCleanup ( ) ;
458- process . exit ( ExitCodes . SUCCESS ) ;
459- } else {
460- // Non-sandbox path: skip loadCliConfig + refreshAuth entirely.
461- // The child process handles all initialization on its own.
462- // This eliminates ~500-1000ms of duplicated work (extensions loading,
463- // hierarchical memory search, policy engine, and 3-5 network calls).
464- await relaunchAppInChildProcess ( memoryArgs , [ ] ) ;
465- }
466- } else {
467- // Non-relaunch path (sandbox env or command mode): auth is needed here
468- // because we won't be relaunching.
360+ async function performEarlyInit ( ) {
469361 const partialConfig = await loadCliConfig (
470362 settings . merged ,
471363 sessionId ,
@@ -476,6 +368,7 @@ export async function main() {
476368 ) ;
477369 adminControlsListner . setConfig ( partialConfig ) ;
478370
371+ let authFailed = false ;
479372 if ( ! settings . merged . security . auth . useExternal && ! argv . isCommand ) {
480373 try {
481374 if (
@@ -509,6 +402,7 @@ export async function main() {
509402
510403 if ( ! ( err instanceof ValidationRequiredError ) ) {
511404 debugLogger . error ( 'Error authenticating:' , err ) ;
405+ authFailed = true ;
512406 }
513407 }
514408 }
@@ -519,6 +413,58 @@ export async function main() {
519413 }
520414
521415 await runDeferredCommand ( settings . merged ) ;
416+
417+ return { partialConfig, authFailed } ;
418+ }
419+
420+ if ( ! process . env [ 'SANDBOX' ] && ! argv . isCommand ) {
421+ const sandboxConfig = await loadSandboxConfig ( settings . merged , argv ) ;
422+
423+ if ( sandboxConfig ) {
424+ const { partialConfig, authFailed } = await performEarlyInit ( ) ;
425+
426+ if ( authFailed ) {
427+ await runExitCleanup ( ) ;
428+ process . exit ( ExitCodes . FATAL_AUTHENTICATION_ERROR ) ;
429+ }
430+ let stdinData = '' ;
431+ if ( ! process . stdin . isTTY ) {
432+ stdinData = await readStdin ( ) ;
433+ }
434+
435+ // This function is a copy of the one from sandbox.ts
436+ // It is moved here to decouple sandbox.ts from the CLI's argument structure.
437+ const injectStdinIntoArgs = (
438+ args : string [ ] ,
439+ stdinData ?: string ,
440+ ) : string [ ] => {
441+ const finalArgs = [ ...args ] ;
442+ if ( stdinData ) {
443+ const promptIndex = finalArgs . findIndex (
444+ ( arg ) => arg === '--prompt' || arg === '-p' ,
445+ ) ;
446+ if ( promptIndex > - 1 && finalArgs . length > promptIndex + 1 ) {
447+ finalArgs [ promptIndex + 1 ] =
448+ `${ stdinData } \n\n${ finalArgs [ promptIndex + 1 ] } ` ;
449+ } else {
450+ finalArgs . push ( '--prompt' , stdinData ) ;
451+ }
452+ }
453+ return finalArgs ;
454+ } ;
455+
456+ const sandboxArgs = injectStdinIntoArgs ( process . argv , stdinData ) ;
457+
458+ await relaunchOnExitCode ( ( ) =>
459+ start_sandbox ( sandboxConfig , memoryArgs , partialConfig , sandboxArgs ) ,
460+ ) ;
461+ await runExitCleanup ( ) ;
462+ process . exit ( ExitCodes . SUCCESS ) ;
463+ } else {
464+ await relaunchAppInChildProcess ( memoryArgs , [ ] ) ;
465+ }
466+ } else {
467+ await performEarlyInit ( ) ;
522468 }
523469
524470 // We are now past the logic handling potentially launching a child process
0 commit comments