// @vitest-environment node import path from 'node:path'; import { beforeEach, describe, expect, it, vi } from 'vitest'; const buildEnrichedEnvMock = vi.fn(); const getCachedShellEnvMock = vi.fn(); const getShellPreferredHomeMock = vi.fn(); const augmentAllConfiguredConnectionEnvMock = vi.fn(); const augmentConfiguredConnectionEnvMock = vi.fn(); const applyConfiguredConnectionEnvMock = vi.fn(); const applyAllConfiguredConnectionEnvMock = vi.fn(); const getConfiguredConnectionIssuesMock = vi.fn(); const getConfiguredConnectionLaunchArgsMock = vi.fn(); const resolveVerifiedOpenCodeRuntimeBinaryPathMock = vi.fn(); const resolveVerifiedAppManagedCodexRuntimeBinaryPathMock = vi.fn(); const resolveAgentTeamsMcpLaunchSpecMock = vi.fn(); vi.mock('@main/utils/cliEnv', () => ({ buildEnrichedEnv: (...args: Parameters) => buildEnrichedEnvMock(...args), })); vi.mock('@main/utils/shellEnv', () => ({ getCachedShellEnv: () => getCachedShellEnvMock(), getShellPreferredHome: () => getShellPreferredHomeMock(), })); vi.mock('../../../../src/main/services/infrastructure/ConfigManager', () => ({ configManager: { getConfig: () => ({ runtime: { providerBackends: { gemini: 'cli', codex: 'codex-native', }, }, }), }, })); vi.mock('../../../../src/main/services/runtime/ProviderConnectionService', () => ({ providerConnectionService: { augmentConfiguredConnectionEnv: ( ...args: Parameters ) => augmentConfiguredConnectionEnvMock(...args), augmentAllConfiguredConnectionEnv: ( ...args: Parameters ) => augmentAllConfiguredConnectionEnvMock(...args), applyConfiguredConnectionEnv: (...args: Parameters) => applyConfiguredConnectionEnvMock(...args), applyAllConfiguredConnectionEnv: ( ...args: Parameters ) => applyAllConfiguredConnectionEnvMock(...args), getConfiguredConnectionLaunchArgs: ( ...args: Parameters ) => getConfiguredConnectionLaunchArgsMock(...args), getConfiguredConnectionIssues: ( ...args: Parameters ) => getConfiguredConnectionIssuesMock(...args), }, })); vi.mock('../../../../src/main/services/infrastructure/OpenCodeRuntimeInstallerService', () => ({ resolveVerifiedOpenCodeRuntimeBinaryPath: () => resolveVerifiedOpenCodeRuntimeBinaryPathMock(), })); vi.mock('@features/codex-runtime-installer/main', () => ({ resolveVerifiedAppManagedCodexRuntimeBinaryPath: () => resolveVerifiedAppManagedCodexRuntimeBinaryPathMock(), })); vi.mock('@main/services/team/TeamMcpConfigBuilder', () => ({ resolveAgentTeamsMcpLaunchSpec: () => resolveAgentTeamsMcpLaunchSpecMock(), })); describe('buildProviderAwareCliEnv', () => { beforeEach(() => { vi.resetModules(); vi.clearAllMocks(); buildEnrichedEnvMock.mockReturnValue({ PATH: '/usr/bin', }); getCachedShellEnvMock.mockReturnValue({ SHELL: '/bin/zsh', }); getShellPreferredHomeMock.mockReturnValue('/Users/tester'); augmentConfiguredConnectionEnvMock.mockImplementation((env: NodeJS.ProcessEnv) => Promise.resolve(env) ); augmentAllConfiguredConnectionEnvMock.mockImplementation((env: NodeJS.ProcessEnv) => Promise.resolve(env) ); applyConfiguredConnectionEnvMock.mockImplementation((env: NodeJS.ProcessEnv) => Promise.resolve(env) ); applyAllConfiguredConnectionEnvMock.mockImplementation((env: NodeJS.ProcessEnv) => Promise.resolve(env) ); getConfiguredConnectionLaunchArgsMock.mockResolvedValue([]); getConfiguredConnectionIssuesMock.mockResolvedValue({}); resolveVerifiedOpenCodeRuntimeBinaryPathMock.mockResolvedValue(null); resolveVerifiedAppManagedCodexRuntimeBinaryPathMock.mockResolvedValue(null); resolveAgentTeamsMcpLaunchSpecMock.mockResolvedValue({ command: 'node', args: ['/app/mcp-server/index.js'], }); }); it('builds provider-pinned CLI env and returns provider-specific issues', async () => { getConfiguredConnectionIssuesMock.mockResolvedValue({ anthropic: 'missing key', }); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ binaryPath: '/mock/claude', providerId: 'anthropic', shellEnv: { EXTRA_FLAG: '1', }, }); expect(buildEnrichedEnvMock).toHaveBeenCalledWith('/mock/claude'); expect(applyConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.objectContaining({ HOME: '/Users/tester', USERPROFILE: '/Users/tester', EXTRA_FLAG: '1', CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST: '1', CLAUDE_CODE_ENTRY_PROVIDER: 'anthropic', }), 'anthropic', undefined ); expect(result.connectionIssues).toEqual({ anthropic: 'missing key', }); expect(result.providerArgs).toEqual([]); }); it('keeps enriched PATH entries when a provider shell env has a narrower PATH', async () => { buildEnrichedEnvMock.mockReturnValue({ PATH: ['/mock/runtime/bin', '/usr/local/bin', '/usr/bin'].join(path.delimiter), }); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ binaryPath: '/mock/claude', providerId: 'codex', shellEnv: { PATH: ['/usr/bin', '/bin'].join(path.delimiter), }, }); expect(result.env.PATH?.split(path.delimiter).slice(0, 4)).toEqual([ '/usr/bin', '/bin', '/mock/runtime/bin', '/usr/local/bin', ]); const appliedEnv = applyConfiguredConnectionEnvMock.mock.calls[0]?.[0] as NodeJS.ProcessEnv; expect(appliedEnv.PATH?.split(path.delimiter).slice(0, 4)).toEqual([ '/usr/bin', '/bin', '/mock/runtime/bin', '/usr/local/bin', ]); expect(applyConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.any(Object), 'codex', undefined ); }); it('passes metadata-only stored API key access through provider env building', async () => { const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); await buildProviderAwareCliEnv({ providerId: 'anthropic', allowStoredApiKeyDecryption: false, }); expect(applyConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.objectContaining({ CLAUDE_CODE_ENTRY_PROVIDER: 'anthropic', }), 'anthropic', undefined, { allowStoredApiKeyDecryption: false } ); }); it('passes a stored API key decrypt allowlist through provider env building', async () => { const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); await buildProviderAwareCliEnv({ providerId: 'anthropic', allowStoredApiKeyDecryption: false, allowedStoredApiKeyEnvVarNames: ['ANTHROPIC_AUTH_TOKEN'], }); expect(applyConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.objectContaining({ CLAUDE_CODE_ENTRY_PROVIDER: 'anthropic', }), 'anthropic', undefined, { allowStoredApiKeyDecryption: false, allowedStoredApiKeyEnvVarNames: ['ANTHROPIC_AUTH_TOKEN'], } ); }); it('passes a stored API key decrypt allowlist through augment env building', async () => { const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); await buildProviderAwareCliEnv({ connectionMode: 'augment', allowStoredApiKeyDecryption: false, allowedStoredApiKeyEnvVarNames: ['ANTHROPIC_AUTH_TOKEN'], }); expect(augmentAllConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.any(Object), { allowStoredApiKeyDecryption: false, allowedStoredApiKeyEnvVarNames: ['ANTHROPIC_AUTH_TOKEN'], } ); expect(applyAllConfiguredConnectionEnvMock).not.toHaveBeenCalled(); }); it('builds shared env for generic CLI launches when no provider is specified', async () => { const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv(); expect(applyAllConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.objectContaining({ HOME: '/Users/tester', USERPROFILE: '/Users/tester', SHELL: '/bin/zsh', }) ); expect(getConfiguredConnectionIssuesMock).toHaveBeenCalledWith( expect.objectContaining({ HOME: '/Users/tester', }) ); expect(result.connectionIssues).toEqual({}); expect(result.providerArgs).toEqual([]); expect(result.env.OPENCODE_DISABLE_AUTOUPDATE).toBe('1'); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND).toBe('node'); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY).toBe('/app/mcp-server/index.js'); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON).toBe( '["/app/mcp-server/index.js"]' ); }); it('adds local Agent Teams MCP launch env for OpenCode provider runtime commands', async () => { const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ providerId: 'opencode', }); expect(resolveAgentTeamsMcpLaunchSpecMock).toHaveBeenCalledTimes(1); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND).toBe('node'); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY).toBe('/app/mcp-server/index.js'); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON).toBe( '["/app/mcp-server/index.js"]' ); }); it('serializes Agent Teams MCP launch env overrides for OpenCode provider commands', async () => { resolveAgentTeamsMcpLaunchSpecMock.mockResolvedValue({ command: '/opt/Agent Teams AI/agent-teams-ai', args: ['/app/mcp-server/index.js'], env: { ELECTRON_RUN_AS_NODE: '1' }, }); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ providerId: 'opencode', env: { ELECTRON_RUN_AS_NODE: 'inherited-global-value' }, }); expect(result.env.ELECTRON_RUN_AS_NODE).toBeUndefined(); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENV_JSON).toBe( '{"ELECTRON_RUN_AS_NODE":"1"}' ); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND).toBe( '/opt/Agent Teams AI/agent-teams-ai' ); }); it('preserves explicit local Agent Teams MCP launch env for OpenCode provider commands', async () => { const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ providerId: 'opencode', env: { CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND: 'custom-node', CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY: '/custom/mcp.js', CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON: '["/custom/mcp.js"]', ELECTRON_RUN_AS_NODE: '1', }, }); expect(resolveAgentTeamsMcpLaunchSpecMock).not.toHaveBeenCalled(); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND).toBe('custom-node'); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY).toBe('/custom/mcp.js'); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON).toBe('["/custom/mcp.js"]'); expect(result.env.CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENV_JSON).toBe( '{"ELECTRON_RUN_AS_NODE":"1"}' ); expect(result.env.ELECTRON_RUN_AS_NODE).toBeUndefined(); }); it('allows OpenCode auto-update only behind an explicit app override', async () => { buildEnrichedEnvMock.mockReturnValue({ PATH: '/usr/bin', OPENCODE_DISABLE_AUTOUPDATE: '1', }); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ env: { CLAUDE_TEAM_OPENCODE_ALLOW_AUTOUPDATE: '1', }, }); expect(result.env.CLAUDE_TEAM_OPENCODE_ALLOW_AUTOUPDATE).toBe('1'); expect(result.env.OPENCODE_DISABLE_AUTOUPDATE).toBeUndefined(); }); it('uses non-destructive credential augmentation for PTY-style envs', async () => { const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ connectionMode: 'augment', env: { OPENAI_API_KEY: 'shell-key', }, }); expect(applyAllConfiguredConnectionEnvMock).not.toHaveBeenCalled(); expect(augmentAllConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.objectContaining({ OPENAI_API_KEY: 'shell-key', }) ); expect(result.connectionIssues).toEqual({}); expect(result.providerArgs).toEqual([]); }); it('preserves caller-provided HOME and USERPROFILE overrides', async () => { const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ providerId: 'anthropic', env: { HOME: '/Users/electron-home', USERPROFILE: '/Users/electron-home', }, }); expect(applyConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.objectContaining({ HOME: '/Users/electron-home', USERPROFILE: '/Users/electron-home', }), 'anthropic', undefined ); expect(result.env.HOME).toBe('/Users/electron-home'); expect(result.env.USERPROFILE).toBe('/Users/electron-home'); expect(result.providerArgs).toEqual([]); }); it('preserves explicit backend overrides passed by the caller', async () => { const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ connectionMode: 'augment', env: { CLAUDE_CODE_GEMINI_BACKEND: 'api', }, }); expect(augmentAllConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.objectContaining({ CLAUDE_CODE_GEMINI_BACKEND: 'api', CLAUDE_CODE_CODEX_BACKEND: 'codex-native', }) ); expect(result.env.CLAUDE_CODE_GEMINI_BACKEND).toBe('api'); expect(result.env.CLAUDE_CODE_CODEX_BACKEND).toBe('codex-native'); expect(result.providerArgs).toEqual([]); }); it('preserves codex-native backend env across provider-aware child env building', async () => { buildEnrichedEnvMock.mockReturnValue({ PATH: '/usr/bin', }); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ providerId: 'codex', }); expect(applyConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.objectContaining({ CLAUDE_CODE_CODEX_BACKEND: 'codex-native', }), 'codex', undefined ); expect(result.env.CLAUDE_CODE_CODEX_BACKEND).toBe('codex-native'); expect(result.providerArgs).toEqual([]); }); it('returns provider launch args for strict codex launches', async () => { getConfiguredConnectionLaunchArgsMock.mockResolvedValue([ '--settings', '{"codex":{"forced_login_method":"chatgpt"}}', ]); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ binaryPath: '/mock/claude-multimodel', providerId: 'codex', }); expect(getConfiguredConnectionLaunchArgsMock).toHaveBeenCalledWith( expect.objectContaining({ CLAUDE_CODE_CODEX_BACKEND: 'codex-native', }), 'codex', undefined, '/mock/claude-multimodel' ); expect(result.providerArgs).toEqual([ '--settings', '{"codex":{"forced_login_method":"chatgpt"}}', ]); }); it('returns Codex custom provider launch args after API-key env application', async () => { applyConfiguredConnectionEnvMock.mockImplementation(async (env: NodeJS.ProcessEnv) => { env.OPENAI_API_KEY = 'stored-key'; env.CODEX_API_KEY = 'stored-key'; return env; }); const customSettings = JSON.stringify({ codex: { forced_login_method: 'api', agent_teams_custom_provider: { config_overrides: [ 'model_provider="agent_teams_custom"', 'model_providers.agent_teams_custom.name="Agent Teams Custom"', 'model_providers.agent_teams_custom.base_url="https://gateway.example.com/v1"', 'model_providers.agent_teams_custom.wire_api="responses"', 'model_providers.agent_teams_custom.env_key="CODEX_API_KEY"', ], }, }, }); getConfiguredConnectionLaunchArgsMock.mockResolvedValue(['--settings', customSettings]); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ binaryPath: '/mock/claude-multimodel', providerId: 'codex', }); expect(getConfiguredConnectionLaunchArgsMock).toHaveBeenCalledWith( expect.objectContaining({ OPENAI_API_KEY: 'stored-key', CODEX_API_KEY: 'stored-key', }), 'codex', undefined, '/mock/claude-multimodel' ); expect(result.providerArgs).toEqual(['--settings', customSettings]); expect(result.env.OPENAI_API_KEY).toBe('stored-key'); expect(result.env.CODEX_API_KEY).toBe('stored-key'); }); it('passes Codex env refreshed by strict credential application into launch args and issue checks', async () => { applyConfiguredConnectionEnvMock.mockImplementation( async (env: NodeJS.ProcessEnv, providerId: string) => { expect(providerId).toBe('codex'); env.CODEX_CLI_PATH = '/Users/tester/.local/bin/codex'; env.CODEX_HOME = '/Users/tester/.codex-custom'; env.CLAUDE_CODE_CODEX_FORCED_LOGIN_METHOD = 'chatgpt'; delete env.OPENAI_API_KEY; delete env.CODEX_API_KEY; return env; } ); getConfiguredConnectionLaunchArgsMock.mockResolvedValue([ '-c', 'forced_login_method="chatgpt"', ]); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ binaryPath: '/mock/claude-multimodel', providerId: 'codex', env: { OPENAI_API_KEY: 'ambient-openai-key', CODEX_API_KEY: 'ambient-codex-key', }, }); const launchArgsEnv = getConfiguredConnectionLaunchArgsMock.mock.calls[0]?.[0] as | NodeJS.ProcessEnv | undefined; expect(launchArgsEnv).toBeDefined(); expect(launchArgsEnv).toMatchObject({ CODEX_CLI_PATH: '/Users/tester/.local/bin/codex', CODEX_HOME: '/Users/tester/.codex-custom', CLAUDE_CODE_CODEX_FORCED_LOGIN_METHOD: 'chatgpt', }); expect(launchArgsEnv?.OPENAI_API_KEY).toBeUndefined(); expect(launchArgsEnv?.CODEX_API_KEY).toBeUndefined(); expect(getConfiguredConnectionLaunchArgsMock).toHaveBeenCalledWith( launchArgsEnv, 'codex', undefined, '/mock/claude-multimodel' ); const connectionIssuesEnv = getConfiguredConnectionIssuesMock.mock.calls[0]?.[0] as | NodeJS.ProcessEnv | undefined; expect(connectionIssuesEnv).toBeDefined(); expect(connectionIssuesEnv).toMatchObject({ CODEX_CLI_PATH: '/Users/tester/.local/bin/codex', CODEX_HOME: '/Users/tester/.codex-custom', CLAUDE_CODE_CODEX_FORCED_LOGIN_METHOD: 'chatgpt', }); expect(connectionIssuesEnv?.OPENAI_API_KEY).toBeUndefined(); expect(connectionIssuesEnv?.CODEX_API_KEY).toBeUndefined(); expect(getConfiguredConnectionIssuesMock).toHaveBeenCalledWith( connectionIssuesEnv, ['codex'], { codex: undefined } ); expect(result.env.CODEX_CLI_PATH).toBe('/Users/tester/.local/bin/codex'); expect(result.env.CODEX_HOME).toBe('/Users/tester/.codex-custom'); expect(result.env.CLAUDE_CODE_CODEX_FORCED_LOGIN_METHOD).toBe('chatgpt'); expect(result.env.OPENAI_API_KEY).toBeUndefined(); expect(result.env.CODEX_API_KEY).toBeUndefined(); expect(result.providerArgs).toEqual(['-c', 'forced_login_method="chatgpt"']); }); it('injects the verified app-managed OpenCode binary for OpenCode launches', async () => { const appManagedBinaryPath = path.join( process.cwd(), 'App Support', 'runtimes', 'opencode', 'current', 'opencode' ); resolveVerifiedOpenCodeRuntimeBinaryPathMock.mockResolvedValue(appManagedBinaryPath); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ providerId: 'opencode', }); expect(applyConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.objectContaining({ CLAUDE_MULTIMODEL_OPENCODE_BIN_PATH: appManagedBinaryPath, OPENCODE_BIN_PATH: appManagedBinaryPath, }), 'opencode', undefined ); expect(result.env.CLAUDE_MULTIMODEL_OPENCODE_BIN_PATH).toBe(appManagedBinaryPath); expect(result.env.OPENCODE_BIN_PATH).toBe(appManagedBinaryPath); expect(result.env.PATH?.split(path.delimiter)[0]).toBe(path.dirname(appManagedBinaryPath)); }); it('exposes an explicit OpenCode binary override on PATH when the app-managed resolver is cold', async () => { const explicitBinaryPath = path.join(process.cwd(), 'custom opencode', 'opencode'); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ providerId: 'opencode', env: { CLAUDE_MULTIMODEL_OPENCODE_BIN_PATH: explicitBinaryPath, }, }); expect(result.env.CLAUDE_MULTIMODEL_OPENCODE_BIN_PATH).toBe(explicitBinaryPath); expect(result.env.OPENCODE_BIN_PATH).toBe(explicitBinaryPath); expect(result.env.PATH?.split(path.delimiter)[0]).toBe(path.dirname(explicitBinaryPath)); }); it('does not inject the app-managed OpenCode binary into non-OpenCode provider launches', async () => { resolveVerifiedOpenCodeRuntimeBinaryPathMock.mockResolvedValue( '/Users/tester/App Support/runtimes/opencode/current/opencode' ); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ providerId: 'anthropic', }); expect(result.env.CLAUDE_MULTIMODEL_OPENCODE_BIN_PATH).toBeUndefined(); expect(result.env.OPENCODE_BIN_PATH).toBeUndefined(); }); it('injects the verified app-managed Codex binary for Codex launches', async () => { resolveVerifiedAppManagedCodexRuntimeBinaryPathMock.mockResolvedValue( '/Users/tester/App Support/runtimes/codex/current/codex' ); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ providerId: 'codex', }); expect(applyConfiguredConnectionEnvMock).toHaveBeenCalledWith( expect.objectContaining({ CODEX_CLI_PATH: '/Users/tester/App Support/runtimes/codex/current/codex', }), 'codex', undefined ); expect(result.env.CODEX_CLI_PATH).toBe( '/Users/tester/App Support/runtimes/codex/current/codex' ); }); it('preserves explicit CODEX_CLI_PATH over the app-managed Codex binary', async () => { resolveVerifiedAppManagedCodexRuntimeBinaryPathMock.mockResolvedValue( '/Users/tester/App Support/runtimes/codex/current/codex' ); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ providerId: 'codex', env: { CODEX_CLI_PATH: '/custom/codex', }, }); expect(result.env.CODEX_CLI_PATH).toBe('/custom/codex'); }); it('does not inject the app-managed Codex binary into non-Codex provider launches', async () => { resolveVerifiedAppManagedCodexRuntimeBinaryPathMock.mockResolvedValue( '/Users/tester/App Support/runtimes/codex/current/codex' ); const { buildProviderAwareCliEnv } = await import('../../../../src/main/services/runtime/providerAwareCliEnv'); const result = await buildProviderAwareCliEnv({ providerId: 'anthropic', }); expect(result.env.CODEX_CLI_PATH).toBeUndefined(); }); });