11import { CODEX_RUNTIME_PROGRESS } from '@features/codex-runtime-installer/contracts' ;
22import { execCli } from '@main/utils/childProcess' ;
3+ import { buildMergedCliPath } from '@main/utils/cliPathMerge' ;
34import { getAppDataPath } from '@main/utils/pathDecoder' ;
45import { safeSendToRenderer } from '@main/utils/safeWebContentsSend' ;
5- import { getCachedShellEnv } from '@main/utils/shellEnv' ;
6+ import { getCachedShellEnv , resolveInteractiveShellEnvBestEffort } from '@main/utils/shellEnv' ;
67import { getErrorMessage } from '@shared/utils/errorHandling' ;
78import { createLogger } from '@shared/utils/logger' ;
89import { createHash , randomUUID } from 'crypto' ;
@@ -27,6 +28,7 @@ const MAX_TARBALL_BYTES = 160 * 1024 * 1024;
2728const MAX_UNPACKED_BYTES = 650 * 1024 * 1024 ;
2829const FETCH_TIMEOUT_MS = 60_000 ;
2930const VERSION_TIMEOUT_MS = 10_000 ;
31+ const PATH_SHELL_ENV_TIMEOUT_MS = 1_500 ;
3032
3133interface NpmPackageMetadata {
3234 name ?: string ;
@@ -149,9 +151,16 @@ function splitPathEnv(pathValue: string | undefined): string[] {
149151 . filter ( Boolean ) ;
150152}
151153
152- function resolvePathCodexBinary ( ) : string | null {
154+ function resolvePathCodexBinary (
155+ additionalEnvSources : ( NodeJS . ProcessEnv | null | undefined ) [ ] = [ ]
156+ ) : string | null {
153157 const shellEnv = getCachedShellEnv ( ) ?? { } ;
154- const pathEntries = [ ...splitPathEnv ( shellEnv . PATH ) , ...splitPathEnv ( process . env . PATH ) ] ;
158+ const pathEntries = [
159+ ...additionalEnvSources . flatMap ( ( env ) => splitPathEnv ( env ?. PATH ) ) ,
160+ ...splitPathEnv ( shellEnv . PATH ) ,
161+ ...splitPathEnv ( buildMergedCliPath ( null ) ) ,
162+ ...splitPathEnv ( process . env . PATH ) ,
163+ ] ;
155164 const seen = new Set < string > ( ) ;
156165 for ( const entry of pathEntries ) {
157166 const normalizedEntry = path . resolve ( entry ) ;
@@ -169,6 +178,21 @@ function resolvePathCodexBinary(): string | null {
169178 return null ;
170179}
171180
181+ async function resolvePathCodexBinaryWithBestEffortEnv (
182+ options : { shellEnvTimeoutMs ?: number } = { }
183+ ) : Promise < string | null > {
184+ const cachedCandidate = resolvePathCodexBinary ( ) ;
185+ if ( cachedCandidate ) {
186+ return cachedCandidate ;
187+ }
188+
189+ const shellEnv = await resolveInteractiveShellEnvBestEffort ( {
190+ timeoutMs : options . shellEnvTimeoutMs ?? PATH_SHELL_ENV_TIMEOUT_MS ,
191+ fallbackEnv : process . env ,
192+ } ) ;
193+ return resolvePathCodexBinary ( [ shellEnv ] ) ;
194+ }
195+
172196export function getCodexRuntimePlatformCandidates (
173197 platform : NodeJS . Platform = process . platform ,
174198 arch : string = process . arch
@@ -543,7 +567,7 @@ export class CodexRuntimeInstallerService implements CodexRuntimeInstallerPort {
543567 }
544568
545569 private async getPathStatus ( ) : Promise < CodexRuntimeStatus > {
546- const binaryPath = resolvePathCodexBinary ( ) ;
570+ const binaryPath = await resolvePathCodexBinaryWithBestEffortEnv ( ) ;
547571 if ( ! binaryPath ) {
548572 return { installed : false , source : 'missing' , state : 'idle' } ;
549573 }
0 commit comments