mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 02:11:28 +00:00
fix: bootstrap explicit CODEX_HOME for ccsxp
This commit is contained in:
@@ -83,6 +83,32 @@ function normalizeCodexReasoningOverride(value: string | number | undefined): st
|
||||
);
|
||||
}
|
||||
|
||||
function ensureExplicitCodexHomeDir(env: NodeJS.ProcessEnv): string | undefined {
|
||||
const codexHome = env.CODEX_HOME?.trim();
|
||||
if (!codexHome) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
fs.mkdirSync(codexHome, { recursive: true });
|
||||
} catch (err) {
|
||||
const error = err as NodeJS.ErrnoException;
|
||||
if (error.code !== 'EEXIST') {
|
||||
return `[X] Unable to initialize CODEX_HOME (${error.code || 'unknown'}): ${codexHome}`;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (!fs.statSync(codexHome).isDirectory()) {
|
||||
return `[X] CODEX_HOME path is not a directory: ${codexHome}`;
|
||||
}
|
||||
return undefined;
|
||||
} catch (err) {
|
||||
const error = err as NodeJS.ErrnoException;
|
||||
return `[X] Unable to access CODEX_HOME (${error.code || 'unknown'}): ${codexHome}`;
|
||||
}
|
||||
}
|
||||
|
||||
export class CodexAdapter implements TargetAdapter {
|
||||
readonly type: TargetType = 'codex';
|
||||
readonly displayName = 'Codex CLI';
|
||||
@@ -207,6 +233,12 @@ export class CodexAdapter implements TargetAdapter {
|
||||
return exitWithCleanup(1);
|
||||
}
|
||||
|
||||
const codexHomeInitError = ensureExplicitCodexHomeDir(env);
|
||||
if (codexHomeInitError) {
|
||||
console.error(codexHomeInitError);
|
||||
return exitWithCleanup(1);
|
||||
}
|
||||
|
||||
const isWindows = process.platform === 'win32';
|
||||
const isPowerShellScript = isWindows && /\.ps1$/i.test(codexPath);
|
||||
const needsShell = isWindows && /\.(cmd|bat)$/i.test(codexPath);
|
||||
|
||||
@@ -270,6 +270,58 @@ process.exit(0);
|
||||
]);
|
||||
});
|
||||
|
||||
it('creates an explicit CODEX_HOME directory before launching native Codex', () => {
|
||||
if (process.platform === 'win32') return;
|
||||
|
||||
const freshCodexHome = path.join(tmpHome, 'fresh-codex-home');
|
||||
const result = runCcsxpAlias(['--version'], {
|
||||
...process.env,
|
||||
CI: '1',
|
||||
NO_COLOR: '1',
|
||||
CCS_HOME: tmpHome,
|
||||
CCS_CODEX_PATH: fakeCodexPath,
|
||||
CCS_TEST_CODEX_ARGS_OUT: codexArgsLogPath,
|
||||
CCS_TEST_CODEX_ENV_OUT: codexEnvLogPath,
|
||||
CCS_TEST_CODEX_VERSION: 'codex-cli 9.9.9-test',
|
||||
CODEX_HOME: freshCodexHome,
|
||||
});
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(fs.existsSync(freshCodexHome)).toBe(true);
|
||||
expect(fs.statSync(freshCodexHome).isDirectory()).toBe(true);
|
||||
expect(readLoggedCodexCalls(codexArgsLogPath)).toEqual([['--version']]);
|
||||
expect(readLoggedCodexEnv(codexEnvLogPath)).toEqual([
|
||||
{
|
||||
CODEX_HOME: freshCodexHome,
|
||||
CODEX_CI: undefined,
|
||||
CODEX_MANAGED_BY_BUN: undefined,
|
||||
CODEX_THREAD_ID: undefined,
|
||||
ANTHROPIC_BASE_URL: undefined,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('fails with a clean error when CODEX_HOME points to a file', () => {
|
||||
if (process.platform === 'win32') return;
|
||||
|
||||
const invalidCodexHome = path.join(tmpHome, 'codex-home-file');
|
||||
fs.writeFileSync(invalidCodexHome, 'not-a-directory');
|
||||
|
||||
const result = runCcsxpAlias(['--version'], {
|
||||
...process.env,
|
||||
CI: '1',
|
||||
NO_COLOR: '1',
|
||||
CCS_HOME: tmpHome,
|
||||
CCS_CODEX_PATH: fakeCodexPath,
|
||||
CCS_TEST_CODEX_ARGS_OUT: codexArgsLogPath,
|
||||
CODEX_HOME: invalidCodexHome,
|
||||
});
|
||||
|
||||
expect(result.status).toBe(1);
|
||||
expect(result.stderr).toContain(`[X] CODEX_HOME path is not a directory: ${invalidCodexHome}`);
|
||||
expect(readLoggedCodexCalls(codexArgsLogPath)).toEqual([]);
|
||||
});
|
||||
|
||||
it('keeps ccsxp pinned to native Codex even when a user passes another --target override', () => {
|
||||
if (process.platform === 'win32') return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user