mirror of
https://github.com/stablyai/orca.git
synced 2026-10-17 16:02:55 +00:00
fix(codex): strip the daemon-inherited Orca CODEX_HOME override for real-home routing
The daemon spawns PTYs from its own inherited environment and honors only spawnOptions.envToDelete, so mutating the sparse env object was not enough to strip an Orca-owned CODEX_HOME the daemon already carries. Add the strip to envToDelete for both daemon host-spawn paths, preserving a user-set CODEX_HOME. Verified live via CDP against a sandboxed dev instance (flag ON): an Orca-spawned pane reports empty CODEX_HOME/ORCA_CODEX_HOME, so Codex resolves its own ~/.codex. Adds daemon-path unit coverage (strip Orca-owned, preserve user-owned, no-op when flag OFF).
This commit is contained in:
@@ -1750,6 +1750,39 @@ describe('registerPtyHandlers', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('strips the daemon-inherited Orca-owned CODEX_HOME for real-home routing', async () => {
|
||||
const spawnOptions = await daemonSpawnAndGetOptions(
|
||||
{},
|
||||
() => null,
|
||||
() => ({ codexSystemDefaultRealHomeEnabled: true }) as never,
|
||||
{ CODEX_HOME: '/managed/home', ORCA_CODEX_HOME: '/managed/home' }
|
||||
)
|
||||
expect(spawnOptions.env.CODEX_HOME).toBeUndefined()
|
||||
expect(spawnOptions.env.ORCA_CODEX_HOME).toBeUndefined()
|
||||
expect(spawnOptions.envToDelete).toEqual(
|
||||
expect.arrayContaining(['CODEX_HOME', 'ORCA_CODEX_HOME'])
|
||||
)
|
||||
})
|
||||
|
||||
it('preserves a daemon-inherited user CODEX_HOME for real-home routing', async () => {
|
||||
const spawnOptions = await daemonSpawnAndGetOptions(
|
||||
{},
|
||||
() => null,
|
||||
() => ({ codexSystemDefaultRealHomeEnabled: true }) as never,
|
||||
{ CODEX_HOME: '/home/me/.config/codex', ORCA_CODEX_HOME: undefined }
|
||||
)
|
||||
expect(spawnOptions.envToDelete).toEqual(expect.arrayContaining(['ORCA_CODEX_HOME']))
|
||||
expect(spawnOptions.envToDelete).not.toEqual(expect.arrayContaining(['CODEX_HOME']))
|
||||
})
|
||||
|
||||
it('does not strip the daemon-inherited CODEX_HOME when the flag is OFF', async () => {
|
||||
const spawnOptions = await daemonSpawnAndGetOptions({}, () => null, undefined, {
|
||||
CODEX_HOME: '/managed/home',
|
||||
ORCA_CODEX_HOME: '/managed/home'
|
||||
})
|
||||
expect(spawnOptions.envToDelete ?? []).not.toEqual(expect.arrayContaining(['CODEX_HOME']))
|
||||
})
|
||||
|
||||
it('prepends the bare-orca CLI shim dir to PATH for packaged Linux spawns', async () => {
|
||||
const originalPlatform = process.platform
|
||||
Object.defineProperty(process, 'platform', {
|
||||
|
||||
+46
-21
@@ -647,12 +647,23 @@ const CODEX_HOME_ENV_KEYS = ['CODEX_HOME', 'ORCA_CODEX_HOME'] as const
|
||||
// the marker so a shell-ready wrapper cannot restore the managed home. A
|
||||
// user-set CODEX_HOME with no Orca marker is preserved untouched (see #8606).
|
||||
function stripInheritedOrcaCodexHomeOverride(baseEnv: Record<string, string>): void {
|
||||
const inheritedOrcaOverride = baseEnv.ORCA_CODEX_HOME ?? process.env.ORCA_CODEX_HOME
|
||||
const inheritedCodexHome = baseEnv.CODEX_HOME ?? process.env.CODEX_HOME
|
||||
if (inheritedOrcaOverride && inheritedCodexHome === inheritedOrcaOverride) {
|
||||
delete baseEnv.CODEX_HOME
|
||||
for (const key of getInheritedOrcaCodexHomeEnvKeysToDelete(baseEnv)) {
|
||||
delete baseEnv[key]
|
||||
}
|
||||
delete baseEnv.ORCA_CODEX_HOME
|
||||
}
|
||||
|
||||
// Why: the daemon spawns the PTY from its own inherited environment and honors
|
||||
// only spawnOptions.envToDelete, so mutating the sparse env object is not enough
|
||||
// to strip an Orca-owned CODEX_HOME the daemon already carries. Return the exact
|
||||
// keys to delete, preserving a user-owned CODEX_HOME.
|
||||
function getInheritedOrcaCodexHomeEnvKeysToDelete(env: Record<string, string>): string[] {
|
||||
const inheritedOrcaOverride = env.ORCA_CODEX_HOME ?? process.env.ORCA_CODEX_HOME
|
||||
const inheritedCodexHome = env.CODEX_HOME ?? process.env.CODEX_HOME
|
||||
const keysToDelete = ['ORCA_CODEX_HOME']
|
||||
if (inheritedOrcaOverride && inheritedCodexHome === inheritedOrcaOverride) {
|
||||
keysToDelete.push('CODEX_HOME')
|
||||
}
|
||||
return keysToDelete
|
||||
}
|
||||
|
||||
type GetSelectedCodexHomePath = (target?: CodexAccountSelectionTarget) => string | null
|
||||
@@ -3082,6 +3093,12 @@ export function registerPtyHandlers(
|
||||
isDaemonHostSpawn &&
|
||||
shouldSkipCodexHomeEnvForWindowsShell(daemonShellOverride, cwd) &&
|
||||
!selectedCodexHomePath
|
||||
const stripInheritedOrcaCodexHome = shouldStripInheritedOrcaCodexHome({
|
||||
target: codexSelectionTarget,
|
||||
selectedCodexHomePath,
|
||||
skipCodexHomeEnv,
|
||||
settings: getSettings?.()
|
||||
})
|
||||
if (isDaemonHostSpawn && sessionId) {
|
||||
if (!isSafePtySessionId(sessionId, app.getPath('userData'))) {
|
||||
throw new Error('Invalid PTY session id')
|
||||
@@ -3091,12 +3108,7 @@ export function registerPtyHandlers(
|
||||
userDataPath: app.getPath('userData'),
|
||||
selectedCodexHomePath,
|
||||
skipCodexHomeEnv,
|
||||
stripInheritedOrcaCodexHome: shouldStripInheritedOrcaCodexHome({
|
||||
target: codexSelectionTarget,
|
||||
selectedCodexHomePath,
|
||||
skipCodexHomeEnv,
|
||||
settings: getSettings?.()
|
||||
}),
|
||||
stripInheritedOrcaCodexHome,
|
||||
githubAttributionEnabled: getSettings?.()?.enableGitHubAttribution ?? false,
|
||||
launchCommand: args.command,
|
||||
launchAgent: isTuiAgent(args.launchAgent) ? args.launchAgent : undefined,
|
||||
@@ -3129,6 +3141,13 @@ export function registerPtyHandlers(
|
||||
spawnOptions.envToDelete,
|
||||
CODEX_HOME_ENV_KEYS
|
||||
)
|
||||
} else if (stripInheritedOrcaCodexHome) {
|
||||
// Why: the daemon inherits its own CODEX_HOME; strip the Orca-owned
|
||||
// override there too, preserving a user-set CODEX_HOME.
|
||||
spawnOptions.envToDelete = mergePtyEnvDeletions(
|
||||
spawnOptions.envToDelete,
|
||||
getInheritedOrcaCodexHomeEnvKeysToDelete(env ?? {})
|
||||
)
|
||||
}
|
||||
deleteRequestedEnvKeys(env, spawnOptions.envToDelete)
|
||||
promoteAgentTeamsShimPath(env, requestedAgentTeamsPath)
|
||||
@@ -3955,6 +3974,12 @@ export function registerPtyHandlers(
|
||||
isDaemonHostSpawn &&
|
||||
shouldSkipCodexHomeEnvForWindowsShell(effectiveShellOverride, cwd) &&
|
||||
!selectedCodexHomePath
|
||||
const stripInheritedOrcaCodexHome = shouldStripInheritedOrcaCodexHome({
|
||||
target: codexSelectionTarget,
|
||||
selectedCodexHomePath,
|
||||
skipCodexHomeEnv,
|
||||
settings: getSettings?.()
|
||||
})
|
||||
if (isDaemonHostSpawn) {
|
||||
if (effectiveSessionId === undefined) {
|
||||
// Should be unreachable: the expression above returns a string when
|
||||
@@ -3979,12 +4004,7 @@ export function registerPtyHandlers(
|
||||
userDataPath: app.getPath('userData'),
|
||||
selectedCodexHomePath,
|
||||
skipCodexHomeEnv,
|
||||
stripInheritedOrcaCodexHome: shouldStripInheritedOrcaCodexHome({
|
||||
target: codexSelectionTarget,
|
||||
selectedCodexHomePath,
|
||||
skipCodexHomeEnv,
|
||||
settings: getSettings?.()
|
||||
}),
|
||||
stripInheritedOrcaCodexHome,
|
||||
githubAttributionEnabled: getSettings?.()?.enableGitHubAttribution ?? false,
|
||||
launchCommand: args.command,
|
||||
launchAgent: isTuiAgent(args.launchAgent) ? args.launchAgent : undefined,
|
||||
@@ -4023,12 +4043,17 @@ export function registerPtyHandlers(
|
||||
const combinedEnvToDelete = mergePtyEnvDeletions(
|
||||
mergePtyEnvDeletions(
|
||||
mergePtyEnvDeletions(
|
||||
mergePtyEnvDeletions(envToDelete, args.envToDelete ?? []),
|
||||
agentTeamsEnvToDelete ?? []
|
||||
mergePtyEnvDeletions(
|
||||
mergePtyEnvDeletions(envToDelete, args.envToDelete ?? []),
|
||||
agentTeamsEnvToDelete ?? []
|
||||
),
|
||||
isDaemonHostSpawn ? getInheritedAgentHookEnvKeysToDelete(spawnEnv) : []
|
||||
),
|
||||
isDaemonHostSpawn ? getInheritedAgentHookEnvKeysToDelete(spawnEnv) : []
|
||||
skipCodexHomeEnv ? CODEX_HOME_ENV_KEYS : []
|
||||
),
|
||||
skipCodexHomeEnv ? CODEX_HOME_ENV_KEYS : []
|
||||
// Why: real-home routing strips the Orca-owned override the daemon
|
||||
// inherits, while preserving a user-set CODEX_HOME.
|
||||
stripInheritedOrcaCodexHome ? getInheritedOrcaCodexHomeEnvKeysToDelete(spawnEnv ?? {}) : []
|
||||
)
|
||||
deleteRequestedEnvKeys(spawnEnv, combinedEnvToDelete)
|
||||
promoteAgentTeamsShimPath(spawnEnv, requestedAgentTeamsPath)
|
||||
|
||||
Reference in New Issue
Block a user