mirror of
https://github.com/stablyai/orca.git
synced 2026-09-23 08:02:31 +00:00
fix(terminal): derive Codex startup marker lifetime from resolved launch
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
// Native Windows shell launch: PowerShell implementations, cmd.exe and Git Bash.
|
||||
import { writeFileSync, mkdirSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import type * as LocalPtyUtils from '../providers/local-pty-utils'
|
||||
|
||||
@@ -348,6 +350,34 @@ describe('createPtySubprocess', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('abandons the default-home marker when Git Bash wrapper materialization fails', async () => {
|
||||
const proc = mockPtyProcess()
|
||||
spawnMock.mockReturnValue(proc)
|
||||
const platform = Object.getOwnPropertyDescriptor(process, 'platform')!
|
||||
const userDataPath = process.env.ORCA_USER_DATA_PATH!
|
||||
// A file occupying the wrapper directory deterministically prevents materialization.
|
||||
mkdirSync(userDataPath, { recursive: true })
|
||||
writeFileSync(join(userDataPath, 'shell-wrappers'), 'occupied')
|
||||
Object.defineProperty(process, 'platform', { value: 'win32' })
|
||||
try {
|
||||
await createPtySubprocess({
|
||||
sessionId: 'test',
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
cwd: 'C:\\Users\\jin\\repo',
|
||||
shellOverride: 'C:\\PortableGit\\bin\\bash.exe',
|
||||
env: { [ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV]: '1' }
|
||||
})
|
||||
} finally {
|
||||
Object.defineProperty(process, 'platform', platform)
|
||||
}
|
||||
expect(spawnMock).toHaveBeenCalledTimes(1)
|
||||
const [shell, args, options] = spawnMock.mock.calls[0]
|
||||
expect(shell).toBe('C:\\PortableGit\\bin\\bash.exe')
|
||||
expect(args).toEqual(['-c', 'chcp.com 65001 >/dev/null 2>&1; exec "$BASH" --login -i'])
|
||||
expect(options.env[ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV]).toBeUndefined()
|
||||
})
|
||||
|
||||
it('keeps the Git Bash wrapper without a managed Codex preflight', async () => {
|
||||
const proc = mockPtyProcess()
|
||||
spawnMock.mockReturnValue(proc)
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
} from '../../providers/macos-tcc-login-shell'
|
||||
import type { WindowsShellSpawnAttempt } from '../../providers/windows-shell-fallback-chain'
|
||||
import { assignHostProcessToKillOnCloseJob } from '../../windows/windows-pty-job'
|
||||
import { scrubCodexDefaultHomeMarkerForWindowsShell } from '../../pty/codex-default-home-shell-startup'
|
||||
import { scrubCodexDefaultHomeMarkerForLaunch } from '../../pty/codex-default-home-shell-startup'
|
||||
|
||||
export type SpawnedDaemonPty = {
|
||||
process: pty.IPty
|
||||
@@ -62,7 +62,7 @@ export function spawnNativeDaemonPty(args: {
|
||||
}
|
||||
for (const attempt of args.windowsFallbackAttempts.slice(1)) {
|
||||
try {
|
||||
scrubCodexDefaultHomeMarkerForWindowsShell(args.env, attempt.shellPath)
|
||||
scrubCodexDefaultHomeMarkerForLaunch(args.env, attempt.supportsCodexDefaultHomeAfterProfile)
|
||||
const process = spawnAt(attempt.shellPath, attempt.shellArgs, attempt.effectiveCwd)
|
||||
const message = primaryErr instanceof Error ? primaryErr.message : String(primaryErr)
|
||||
console.warn(
|
||||
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
import { ORCA_HERMES_STARTUP_QUERY_ENV } from '../../../shared/hermes-startup-query'
|
||||
import {
|
||||
ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV,
|
||||
scrubCodexDefaultHomeMarkerForWindowsShell
|
||||
scrubCodexDefaultHomeMarkerForLaunch
|
||||
} from '../../pty/codex-default-home-shell-startup'
|
||||
import { WINDOWS_GIT_BASH_SHELL } from '../../../shared/windows-terminal-shell'
|
||||
import { getShellLaunchConfig, resolvePtyShellPath } from '../shell-ready'
|
||||
@@ -72,8 +72,6 @@ export function createPtyShellLaunchPlan(
|
||||
let validationCwd = spawnCwd
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
// Why: execution-host reconciliation may preserve a daemon-only custom home
|
||||
// by dropping the reset, but that must not also disable shell integration.
|
||||
const useGitBashShellReadyWrapper =
|
||||
opts.env?.[ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV] !== undefined
|
||||
const normalizedShellFamily = pathWin32.basename(shellPath).toLowerCase()
|
||||
@@ -117,8 +115,11 @@ export function createPtyShellLaunchPlan(
|
||||
wslContext: resolvedWslContext,
|
||||
startupCommand: opts.command
|
||||
})
|
||||
let supportsCodexDefaultHomeAfterProfile = false
|
||||
const primaryAttempt = windowsFallbackAttempts[0]
|
||||
if (primaryAttempt) {
|
||||
supportsCodexDefaultHomeAfterProfile =
|
||||
primaryAttempt.supportsCodexDefaultHomeAfterProfile === true
|
||||
shellPath = primaryAttempt.shellPath
|
||||
shellArgs = primaryAttempt.shellArgs
|
||||
spawnCwd = primaryAttempt.effectiveCwd
|
||||
@@ -134,6 +135,7 @@ export function createPtyShellLaunchPlan(
|
||||
env.ORCA_CODEX_LAUNCH_PREFLIGHT,
|
||||
useGitBashShellReadyWrapper
|
||||
)
|
||||
supportsCodexDefaultHomeAfterProfile = resolved.supportsCodexDefaultHomeAfterProfile === true
|
||||
shellArgs = resolved.shellArgs
|
||||
spawnCwd = resolved.effectiveCwd
|
||||
validationCwd = resolved.validationCwd
|
||||
@@ -163,6 +165,8 @@ export function createPtyShellLaunchPlan(
|
||||
env.ORCA_CODEX_LAUNCH_PREFLIGHT,
|
||||
useGitBashShellReadyWrapper
|
||||
)
|
||||
supportsCodexDefaultHomeAfterProfile =
|
||||
resolved.supportsCodexDefaultHomeAfterProfile === true
|
||||
shellArgs = resolved.shellArgs
|
||||
spawnCwd = resolved.effectiveCwd
|
||||
validationCwd = resolved.validationCwd
|
||||
@@ -189,7 +193,7 @@ export function createPtyShellLaunchPlan(
|
||||
if (pathWin32.basename(shellPath).toLowerCase() === 'wsl.exe') {
|
||||
addOrcaWslInteropEnv(env)
|
||||
}
|
||||
scrubCodexDefaultHomeMarkerForWindowsShell(env, shellPath)
|
||||
scrubCodexDefaultHomeMarkerForLaunch(env, supportsCodexDefaultHomeAfterProfile)
|
||||
} else {
|
||||
rescrubDaemonPtyEnvironment(env, opts)
|
||||
const preferredShellPath = shellPath
|
||||
|
||||
@@ -45,6 +45,7 @@ export type LocalPtyLaunchPlan = {
|
||||
shellArgs: string[]
|
||||
effectiveCwd: string
|
||||
validationCwd: string
|
||||
supportsCodexDefaultHomeAfterProfile?: boolean
|
||||
startupCommandDeliveredInShellArgs: boolean
|
||||
windowsFallbackAttempts: ReturnType<typeof buildWindowsPowerShellSpawnAttempts>
|
||||
shellReadyLaunch: ReturnType<typeof getShellLaunchConfig> | null
|
||||
@@ -72,6 +73,7 @@ function finalizeLocalPtyLaunchPlan(
|
||||
shellArgs: string[]
|
||||
effectiveCwd: string
|
||||
validationCwd: string
|
||||
supportsCodexDefaultHomeAfterProfile?: boolean
|
||||
startupCommandDeliveredInShellArgs?: boolean
|
||||
windowsFallbackAttempts?: ReturnType<typeof buildWindowsPowerShellSpawnAttempts>
|
||||
}
|
||||
@@ -91,6 +93,7 @@ function finalizeLocalPtyLaunchPlan(
|
||||
preferredWslContext: seed.preferredWslContext,
|
||||
launchWslContext: seed.launchWslContext,
|
||||
shellPath: shell.shellPath,
|
||||
supportsCodexDefaultHomeAfterProfile: shell.supportsCodexDefaultHomeAfterProfile,
|
||||
shellArgs: shell.shellArgs,
|
||||
effectiveCwd: shell.effectiveCwd,
|
||||
validationCwd: shell.validationCwd,
|
||||
@@ -162,6 +165,7 @@ function createWindowsLocalPtyLaunchPlan(
|
||||
if (primaryAttempt) {
|
||||
return finalizeLocalPtyLaunchPlan(seed, {
|
||||
shellPath: primaryAttempt.shellPath,
|
||||
supportsCodexDefaultHomeAfterProfile: primaryAttempt.supportsCodexDefaultHomeAfterProfile,
|
||||
shellArgs: primaryAttempt.shellArgs,
|
||||
effectiveCwd: primaryAttempt.effectiveCwd,
|
||||
validationCwd: primaryAttempt.validationCwd,
|
||||
@@ -178,6 +182,7 @@ function createWindowsLocalPtyLaunchPlan(
|
||||
)
|
||||
return finalizeLocalPtyLaunchPlan(seed, {
|
||||
shellPath,
|
||||
supportsCodexDefaultHomeAfterProfile: resolved.supportsCodexDefaultHomeAfterProfile,
|
||||
shellArgs: resolved.shellArgs,
|
||||
effectiveCwd: resolved.effectiveCwd,
|
||||
validationCwd: resolved.validationCwd,
|
||||
@@ -229,6 +234,7 @@ export function createLocalPtyLaunchPlan(
|
||||
const resolved = resolveWindowsShellLaunchArgs(shellPath, cwd, defaultCwd)
|
||||
return finalizeLocalPtyLaunchPlan(seed, {
|
||||
shellPath,
|
||||
supportsCodexDefaultHomeAfterProfile: resolved.supportsCodexDefaultHomeAfterProfile,
|
||||
shellArgs: resolved.shellArgs,
|
||||
effectiveCwd: resolved.effectiveCwd,
|
||||
validationCwd: resolved.validationCwd
|
||||
|
||||
@@ -632,6 +632,40 @@ describe('LocalPtyProvider', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('abandons the default-home marker when Git Bash wrapper writing fails', async () => {
|
||||
spawnMock.mockClear()
|
||||
Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' })
|
||||
statSyncMock.mockImplementation((path: string) => {
|
||||
if (String(path).includes('shell-wrappers')) {
|
||||
throw new Error('ENOENT')
|
||||
}
|
||||
return { isDirectory: () => true, mode: 0o755, size: 1 }
|
||||
})
|
||||
writeFileSyncMock.mockImplementation(() => {
|
||||
throw new Error('ENOSPC')
|
||||
})
|
||||
provider.configure({
|
||||
buildSpawnEnv: (_id, env) => ({
|
||||
...env,
|
||||
[ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV]: '1'
|
||||
})
|
||||
})
|
||||
|
||||
await provider.spawn({
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
cwd: 'C:\\Users\\jin\\repo',
|
||||
shellOverride: 'C:\\PortableGit\\bin\\bash.exe'
|
||||
})
|
||||
|
||||
expect(writeFileSyncMock).toHaveBeenCalledTimes(1)
|
||||
expect(spawnMock).toHaveBeenCalledTimes(1)
|
||||
const [shell, args, options] = spawnMock.mock.calls[0]
|
||||
expect(shell).toBe('C:\\PortableGit\\bin\\bash.exe')
|
||||
expect(args).toEqual(['-c', 'chcp.com 65001 >/dev/null 2>&1; exec "$BASH" --login -i'])
|
||||
expect(options.env[ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV]).toBeUndefined()
|
||||
})
|
||||
|
||||
it('keeps the Git Bash wrapper without a managed Codex preflight', async () => {
|
||||
const platform = Object.getOwnPropertyDescriptor(process, 'platform')
|
||||
const originalProgramFiles = process.env.ProgramFiles
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { WindowsShellSpawnAttempt } from './windows-shell-fallback-chain'
|
||||
export type { WindowsShellSpawnAttempt } from './windows-shell-fallback-chain'
|
||||
import { basename, isAbsolute, join } from 'node:path'
|
||||
import { existsSync, accessSync, statSync, chmodSync, constants as fsConstants } from 'node:fs'
|
||||
import type * as pty from 'node-pty'
|
||||
@@ -7,7 +9,7 @@ import {
|
||||
wrapShellSpawnForMacosTccAttribution
|
||||
} from './macos-tcc-login-shell'
|
||||
import { formatLocalPtyEnvironmentDiag } from './working-directory-validation'
|
||||
import { scrubCodexDefaultHomeMarkerForWindowsShell } from '../pty/codex-default-home-shell-startup'
|
||||
import { scrubCodexDefaultHomeMarkerForLaunch } from '../pty/codex-default-home-shell-startup'
|
||||
|
||||
export {
|
||||
formatLocalPtyEnvironmentDiag,
|
||||
@@ -111,17 +113,6 @@ export function ensureNodePtySpawnHelperExecutable(): void {
|
||||
}
|
||||
}
|
||||
|
||||
/** A pre-resolved Windows shell attempt: an absolute executable plus the launch
|
||||
* args + cwd computed for it. Used to walk the PowerShell -> Windows PowerShell
|
||||
* -> cmd.exe fallback chain when ConPTY rejects the primary shell. */
|
||||
export type WindowsShellSpawnAttempt = {
|
||||
shellPath: string
|
||||
shellArgs: string[]
|
||||
effectiveCwd: string
|
||||
validationCwd: string
|
||||
startupCommandDeliveredInShellArgs: boolean
|
||||
}
|
||||
|
||||
export type ShellSpawnParams = {
|
||||
shellPath: string
|
||||
shellArgs: string[]
|
||||
@@ -185,7 +176,7 @@ function spawnWindowsFallbackChain(
|
||||
// Skip the first entry: it is the primary that already failed above.
|
||||
for (const attempt of attempts.slice(1)) {
|
||||
try {
|
||||
scrubCodexDefaultHomeMarkerForWindowsShell(env, attempt.shellPath)
|
||||
scrubCodexDefaultHomeMarkerForLaunch(env, attempt.supportsCodexDefaultHomeAfterProfile)
|
||||
const proc = ptySpawn(attempt.shellPath, attempt.shellArgs, {
|
||||
name: termName,
|
||||
cols,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { parseWslPath } from '../wsl'
|
||||
import { isWindowsGitBashShellPath } from '../git-bash'
|
||||
import {
|
||||
ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV,
|
||||
scrubCodexDefaultHomeMarkerForWindowsShell
|
||||
scrubCodexDefaultHomeMarkerForLaunch
|
||||
} from '../pty/codex-default-home-shell-startup'
|
||||
import type { LocalPtyLaunchPlan } from './local-pty-launch-plan'
|
||||
import {
|
||||
@@ -41,6 +41,7 @@ export function finalizeWindowsLocalPtySpawnEnvironment(args: {
|
||||
distro: codexHomeWslInfo.distro
|
||||
}
|
||||
)
|
||||
plan.supportsCodexDefaultHomeAfterProfile = resolved.supportsCodexDefaultHomeAfterProfile
|
||||
plan.shellArgs = resolved.shellArgs
|
||||
plan.effectiveCwd = resolved.effectiveCwd
|
||||
plan.validationCwd = resolved.validationCwd
|
||||
@@ -72,7 +73,6 @@ export function finalizeWindowsLocalPtySpawnEnvironment(args: {
|
||||
const shellBasename = pathWin32.basename(plan.shellPath).toLowerCase()
|
||||
const codexLaunchPreflightCommand = env.ORCA_CODEX_LAUNCH_PREFLIGHT
|
||||
const useGitBashShellReadyWrapper = env[ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV] !== undefined
|
||||
scrubCodexDefaultHomeMarkerForWindowsShell(env, plan.shellPath)
|
||||
if (
|
||||
(codexLaunchPreflightCommand || useGitBashShellReadyWrapper) &&
|
||||
((shellBasename === 'cmd.exe' && Boolean(codexLaunchPreflightCommand)) ||
|
||||
@@ -91,9 +91,11 @@ export function finalizeWindowsLocalPtySpawnEnvironment(args: {
|
||||
codexLaunchPreflightCommand,
|
||||
useGitBashShellReadyWrapper
|
||||
)
|
||||
plan.supportsCodexDefaultHomeAfterProfile = resolved.supportsCodexDefaultHomeAfterProfile
|
||||
plan.shellArgs = resolved.shellArgs
|
||||
plan.effectiveCwd = resolved.effectiveCwd
|
||||
plan.validationCwd = resolved.validationCwd
|
||||
plan.startupCommandDeliveredInShellArgs = resolved.startupCommandDeliveredInShellArgs === true
|
||||
}
|
||||
scrubCodexDefaultHomeMarkerForLaunch(env, plan.supportsCodexDefaultHomeAfterProfile)
|
||||
}
|
||||
|
||||
@@ -32,20 +32,23 @@ const GIT_BASH_UTF8_LOGIN_COMMAND = 'chcp.com 65001 >/dev/null 2>&1; exec "$BASH
|
||||
function getGitBashLaunchCommand(
|
||||
codexLaunchPreflightCommand?: string,
|
||||
useGitBashShellReadyWrapper = false
|
||||
): string {
|
||||
): { command: string; supportsCodexDefaultHomeAfterProfile: boolean } {
|
||||
if (!codexLaunchPreflightCommand && !useGitBashShellReadyWrapper) {
|
||||
return GIT_BASH_UTF8_LOGIN_COMMAND
|
||||
return { command: GIT_BASH_UTF8_LOGIN_COMMAND, supportsCodexDefaultHomeAfterProfile: false }
|
||||
}
|
||||
|
||||
ensureShellReadyWrappersAt()
|
||||
const wrapperArgs = getBashWrapperLaunchArgs()
|
||||
if (!wrapperArgs) {
|
||||
return GIT_BASH_UTF8_LOGIN_COMMAND
|
||||
return { command: GIT_BASH_UTF8_LOGIN_COMMAND, supportsCodexDefaultHomeAfterProfile: false }
|
||||
}
|
||||
const bashArgs = [...wrapperArgs, '-i']
|
||||
.map((arg) => (arg.startsWith('-') ? arg : quotePosixShell(arg.replace(/\\/g, '/'))))
|
||||
.join(' ')
|
||||
return `chcp.com 65001 >/dev/null 2>&1; exec "$BASH" ${bashArgs}`
|
||||
return {
|
||||
command: `chcp.com 65001 >/dev/null 2>&1; exec "$BASH" ${bashArgs}`,
|
||||
supportsCodexDefaultHomeAfterProfile: true
|
||||
}
|
||||
}
|
||||
|
||||
/** Result of resolving a Windows shell to its launch args + effective cwd.
|
||||
@@ -57,6 +60,8 @@ function getGitBashLaunchCommand(
|
||||
* shellOverride never reached the daemon's shell-args branches. Sharing the
|
||||
* decision here keeps both paths honest. */
|
||||
export type WindowsShellLaunchArgs = {
|
||||
/** Set only when the resolved launch actually installs the post-profile consumer. */
|
||||
supportsCodexDefaultHomeAfterProfile?: boolean
|
||||
shellArgs: string[]
|
||||
/** True when the startup command was embedded in shellArgs and must not be
|
||||
* written again through stdin. */
|
||||
@@ -210,6 +215,7 @@ export function resolveWindowsShellLaunchArgs(
|
||||
// Why base64 and not -Command: see powershell-osc133-bootstrap.ts (MDE review).
|
||||
return {
|
||||
shellArgs: ['-NoLogo', '-NoExit', '-EncodedCommand', powerShellCommand.encodedCommand],
|
||||
supportsCodexDefaultHomeAfterProfile: true,
|
||||
...(powerShellCommand.startupCommandDeliveredInShellArgs
|
||||
? { startupCommandDeliveredInShellArgs: true }
|
||||
: {}),
|
||||
@@ -219,11 +225,10 @@ export function resolveWindowsShellLaunchArgs(
|
||||
}
|
||||
|
||||
if (isWindowsGitBashShellPath(shellPath)) {
|
||||
const launch = getGitBashLaunchCommand(codexLaunchPreflightCommand, useGitBashShellReadyWrapper)
|
||||
return {
|
||||
shellArgs: [
|
||||
'-c',
|
||||
getGitBashLaunchCommand(codexLaunchPreflightCommand, useGitBashShellReadyWrapper)
|
||||
],
|
||||
shellArgs: ['-c', launch.command],
|
||||
supportsCodexDefaultHomeAfterProfile: launch.supportsCodexDefaultHomeAfterProfile,
|
||||
effectiveCwd: nativeCwd,
|
||||
validationCwd: nativeCwd
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
/** A single attempt in the Windows shell-spawn fallback chain: the absolute
|
||||
* executable plus the launch args + cwd computed for it. */
|
||||
export type WindowsShellSpawnAttempt = {
|
||||
supportsCodexDefaultHomeAfterProfile?: boolean
|
||||
shellPath: string
|
||||
shellArgs: string[]
|
||||
effectiveCwd: string
|
||||
@@ -32,6 +33,7 @@ function toAttempt(
|
||||
)
|
||||
return {
|
||||
shellPath,
|
||||
supportsCodexDefaultHomeAfterProfile: resolved.supportsCodexDefaultHomeAfterProfile,
|
||||
shellArgs: resolved.shellArgs,
|
||||
effectiveCwd: resolved.effectiveCwd,
|
||||
validationCwd: resolved.validationCwd,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV,
|
||||
reconcileDaemonCodexDefaultHomeMarker,
|
||||
scrubCodexDefaultHomeMarkerForWindowsShell
|
||||
scrubCodexDefaultHomeMarkerForLaunch
|
||||
} from './codex-default-home-shell-startup'
|
||||
|
||||
describe('reconcileDaemonCodexDefaultHomeMarker', () => {
|
||||
@@ -63,29 +63,15 @@ describe('reconcileDaemonCodexDefaultHomeMarker', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('scrubCodexDefaultHomeMarkerForWindowsShell', () => {
|
||||
it.each([
|
||||
'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe',
|
||||
'C:\\Program Files\\PowerShell\\7\\pwsh.exe',
|
||||
'C:\\Program Files\\Git\\bin\\bash.exe'
|
||||
])('keeps the one-shot marker for a consuming shell: %s', (shellPath) => {
|
||||
const env = { [ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV]: '1' }
|
||||
|
||||
scrubCodexDefaultHomeMarkerForWindowsShell(env, shellPath)
|
||||
|
||||
expect(env[ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV]).toBe('1')
|
||||
})
|
||||
|
||||
it.each(['cmd.exe', 'wsl.exe', 'C:\\msys64\\usr\\bin\\bash.exe'])(
|
||||
'removes the marker before an unwrapped shell: %s',
|
||||
(shellPath) => {
|
||||
const env: Record<string, string> = {
|
||||
[ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV]: '1'
|
||||
}
|
||||
|
||||
scrubCodexDefaultHomeMarkerForWindowsShell(env, shellPath)
|
||||
|
||||
expect(env[ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV]).toBeUndefined()
|
||||
describe('scrubCodexDefaultHomeMarkerForLaunch', () => {
|
||||
it.each([true, false, undefined])(
|
||||
'retains the marker only with a consumer: %s',
|
||||
(supportsConsumer) => {
|
||||
const env = { [ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV]: '1' }
|
||||
scrubCodexDefaultHomeMarkerForLaunch(env, supportsConsumer)
|
||||
expect(env[ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV]).toBe(
|
||||
supportsConsumer ? '1' : undefined
|
||||
)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import { win32 as pathWin32 } from 'node:path'
|
||||
import { isWindowsGitBashShellPath } from '../git-bash'
|
||||
|
||||
export const ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV = 'ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE'
|
||||
export const ORCA_CODEX_DEFAULT_HOME_UNSET_AFTER_PROFILE = '1'
|
||||
|
||||
@@ -24,16 +21,11 @@ export function reconcileDaemonCodexDefaultHomeMarker(
|
||||
}
|
||||
|
||||
/** Drops the one-shot marker from shells whose startup path cannot consume it. */
|
||||
export function scrubCodexDefaultHomeMarkerForWindowsShell(
|
||||
export function scrubCodexDefaultHomeMarkerForLaunch(
|
||||
env: Record<string, string>,
|
||||
shellPath: string
|
||||
supportsCodexDefaultHomeAfterProfile: boolean | undefined
|
||||
): void {
|
||||
const shellName = pathWin32.basename(shellPath).toLowerCase()
|
||||
if (
|
||||
shellName !== 'powershell.exe' &&
|
||||
shellName !== 'pwsh.exe' &&
|
||||
!isWindowsGitBashShellPath(shellPath)
|
||||
) {
|
||||
if (!supportsCodexDefaultHomeAfterProfile) {
|
||||
delete env[ORCA_CODEX_DEFAULT_HOME_AFTER_PROFILE_ENV]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user