feat(codex): add ccsxp runtime shortcut

This commit is contained in:
Tam Nhu Tran
2026-03-29 19:43:26 -04:00
parent 325137fd38
commit deb1e9d71e
6 changed files with 164 additions and 15 deletions
+2 -1
View File
@@ -30,7 +30,8 @@
"ccs-droid": "dist/bin/droid-runtime.js", "ccs-droid": "dist/bin/droid-runtime.js",
"ccsd": "dist/bin/droid-runtime.js", "ccsd": "dist/bin/droid-runtime.js",
"ccs-codex": "dist/bin/codex-runtime.js", "ccs-codex": "dist/bin/codex-runtime.js",
"ccsx": "dist/bin/codex-runtime.js" "ccsx": "dist/bin/codex-runtime.js",
"ccsxp": "dist/bin/ccsxp-runtime.js"
}, },
"files": [ "files": [
"dist/", "dist/",
+9
View File
@@ -0,0 +1,9 @@
const { stripTargetFlag } = require('../targets/target-resolver');
process.env.CCS_INTERNAL_ENTRY_TARGET = 'codex';
// ccsxp is an opinionated shortcut for the built-in Codex-on-Codex route.
// Strip user-supplied target overrides before forcing the shortcut target.
const forwardedArgs = stripTargetFlag(process.argv.slice(2));
process.argv.splice(2, process.argv.length - 2, 'codex', '--target', 'codex', ...forwardedArgs);
require('../ccs');
+22 -6
View File
@@ -241,14 +241,26 @@ function resolveNativeClaudeLaunchArgs(
} }
function shouldPassthroughNativeCodexFlagCommand(args: string[]): boolean { function shouldPassthroughNativeCodexFlagCommand(args: string[]): boolean {
return getNativeCodexPassthroughArgs(args) !== null;
}
function getNativeCodexPassthroughArgs(args: string[]): string[] | null {
const targetArgs = stripTargetFlag(args); const targetArgs = stripTargetFlag(args);
if (targetArgs.length === 0) { if (resolveTargetType(args) !== 'codex' || targetArgs.length === 0) {
return false; return null;
} }
return ( const firstArg = targetArgs[0] || '';
resolveTargetType(args) === 'codex' && CODEX_NATIVE_PASSTHROUGH_FLAGS.has(targetArgs[0] || '') if (CODEX_NATIVE_PASSTHROUGH_FLAGS.has(firstArg)) {
); return targetArgs;
}
const secondArg = targetArgs[1] || '';
if (firstArg === 'codex' && CODEX_NATIVE_PASSTHROUGH_FLAGS.has(secondArg)) {
return targetArgs.slice(1);
}
return null;
} }
function execNativeCodexFlagCommand(args: string[]): void { function execNativeCodexFlagCommand(args: string[]): void {
@@ -265,7 +277,11 @@ function execNativeCodexFlagCommand(args: string[]): void {
process.exit(1); process.exit(1);
} }
const targetArgs = stripTargetFlag(args); const targetArgs = getNativeCodexPassthroughArgs(args);
if (!targetArgs) {
console.error(fail('Native Codex passthrough args could not be resolved.'));
process.exit(1);
}
const creds: TargetCredentials = { const creds: TargetCredentials = {
profile: 'default', profile: 'default',
baseUrl: '', baseUrl: '',
+15 -2
View File
@@ -8,7 +8,7 @@ try {
expandPath = require('../../dist/utils/helpers').expandPath; expandPath = require('../../dist/utils/helpers').expandPath;
} catch (e) { } catch (e) {
// If helpers module doesn't exist or doesn't export expandPath, create a mock // If helpers module doesn't exist or doesn't export expandPath, create a mock
expandPath = function(p) { expandPath = function (p) {
if (!p || typeof p !== 'string') return p; if (!p || typeof p !== 'string') return p;
if (p.startsWith('~/')) { if (p.startsWith('~/')) {
return path.join(os.homedir(), p.slice(2)); return path.join(os.homedir(), p.slice(2));
@@ -76,7 +76,10 @@ describe('cross-platform', () => {
describe('platform-specific behavior', () => { describe('platform-specific behavior', () => {
it('detects platform correctly', () => { it('detects platform correctly', () => {
const platform = os.platform(); const platform = os.platform();
assert(['darwin', 'linux', 'win32'].includes(platform), 'Should be running on supported platform'); assert(
['darwin', 'linux', 'win32'].includes(platform),
'Should be running on supported platform'
);
}); });
it('handles path separators correctly', () => { it('handles path separators correctly', () => {
@@ -133,6 +136,7 @@ describe('cross-platform', () => {
assert(packageJson.bin.ccsd, 'bin field should specify ccsd command'); assert(packageJson.bin.ccsd, 'bin field should specify ccsd command');
assert(packageJson.bin['ccs-codex'], 'bin field should specify ccs-codex command'); assert(packageJson.bin['ccs-codex'], 'bin field should specify ccs-codex command');
assert(packageJson.bin.ccsx, 'bin field should specify ccsx command'); assert(packageJson.bin.ccsx, 'bin field should specify ccsx command');
assert(packageJson.bin.ccsxp, 'bin field should specify ccsxp command');
assert.notStrictEqual( assert.notStrictEqual(
packageJson.bin['ccs-droid'], packageJson.bin['ccs-droid'],
packageJson.bin.ccs, packageJson.bin.ccs,
@@ -153,6 +157,11 @@ describe('cross-platform', () => {
packageJson.bin.ccsx, packageJson.bin.ccsx,
'ccsx should share the dedicated codex runtime entrypoint' 'ccsx should share the dedicated codex runtime entrypoint'
); );
assert.notStrictEqual(
packageJson.bin.ccsxp,
packageJson.bin.ccsx,
'ccsxp should use a dedicated shortcut entrypoint'
);
assert( assert(
fs.existsSync(path.join(__dirname, '..', '..', packageJson.bin['ccs-droid'])), fs.existsSync(path.join(__dirname, '..', '..', packageJson.bin['ccs-droid'])),
'dedicated droid runtime entrypoint should exist' 'dedicated droid runtime entrypoint should exist'
@@ -161,6 +170,10 @@ describe('cross-platform', () => {
fs.existsSync(path.join(__dirname, '..', '..', packageJson.bin['ccs-codex'])), fs.existsSync(path.join(__dirname, '..', '..', packageJson.bin['ccs-codex'])),
'dedicated codex runtime entrypoint should exist' 'dedicated codex runtime entrypoint should exist'
); );
assert(
fs.existsSync(path.join(__dirname, '..', '..', packageJson.bin.ccsxp)),
'dedicated ccsxp shortcut entrypoint should exist'
);
assert(packageJson.scripts, 'package.json should have scripts field'); assert(packageJson.scripts, 'package.json should have scripts field');
}); });
}); });
+55
View File
@@ -0,0 +1,55 @@
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
const wrapperPath = require.resolve('../../../src/bin/ccsxp-runtime.ts');
const ccsPath = require.resolve('../../../src/ccs.ts');
describe('ccsxp runtime wrapper', () => {
const originalArgv = process.argv;
const originalEntryTarget = process.env.CCS_INTERNAL_ENTRY_TARGET;
beforeEach(() => {
delete require.cache[wrapperPath];
delete require.cache[ccsPath];
});
afterEach(() => {
process.argv = originalArgv;
if (originalEntryTarget === undefined) {
delete process.env.CCS_INTERNAL_ENTRY_TARGET;
} else {
process.env.CCS_INTERNAL_ENTRY_TARGET = originalEntryTarget;
}
delete require.cache[wrapperPath];
delete require.cache[ccsPath];
});
it('prepends the built-in codex profile and target before loading CCS', () => {
process.argv = ['node', wrapperPath, 'fix failing tests'];
require.cache[ccsPath] = { exports: {} } as NodeJS.Module;
require(wrapperPath);
expect(process.env.CCS_INTERNAL_ENTRY_TARGET).toBe('codex');
expect(process.argv.slice(2)).toEqual(['codex', '--target', 'codex', 'fix failing tests']);
});
it('keeps flag-only invocations routed through the built-in codex profile shortcut', () => {
process.argv = ['node', wrapperPath, '--version'];
require.cache[ccsPath] = { exports: {} } as NodeJS.Module;
require(wrapperPath);
expect(process.argv.slice(2)).toEqual(['codex', '--target', 'codex', '--version']);
});
it('strips user-supplied target overrides before forcing the codex shortcut target', () => {
process.argv = ['node', wrapperPath, '--target', 'claude', '--version'];
require.cache[ccsPath] = { exports: {} } as NodeJS.Module;
require(wrapperPath);
expect(process.argv.slice(2)).toEqual(['codex', '--target', 'codex', '--version']);
});
});
@@ -40,6 +40,21 @@ function runCodexAlias(args: string[], env: NodeJS.ProcessEnv): RunResult {
}; };
} }
function runCcsxpAlias(args: string[], env: NodeJS.ProcessEnv): RunResult {
const ccsxpEntry = path.join(process.cwd(), 'src', 'bin', 'ccsxp-runtime.ts');
const result = spawnSync(process.execPath, [ccsxpEntry, ...args], {
encoding: 'utf8',
env,
timeout: 20000,
});
return {
status: result.status,
stdout: result.stdout || '',
stderr: result.stderr || '',
};
}
function readLoggedCodexCalls(logPath: string): string[][] { function readLoggedCodexCalls(logPath: string): string[][] {
if (!fs.existsSync(logPath)) { if (!fs.existsSync(logPath)) {
return []; return [];
@@ -94,8 +109,9 @@ describe('codex runtime integration', () => {
`#!/usr/bin/env node `#!/usr/bin/env node
const fs = require('fs'); const fs = require('fs');
const out = process.env.CCS_TEST_CODEX_ARGS_OUT; const out = process.env.CCS_TEST_CODEX_ARGS_OUT;
const cliArgs = process.argv.slice(2);
if (out) { if (out) {
fs.appendFileSync(out, JSON.stringify(process.argv.slice(2)) + '\\n'); fs.appendFileSync(out, JSON.stringify(cliArgs) + '\\n');
} }
const envOut = process.env.CCS_TEST_CODEX_ENV_OUT; const envOut = process.env.CCS_TEST_CODEX_ENV_OUT;
if (envOut) { if (envOut) {
@@ -110,11 +126,11 @@ if (envOut) {
}) + '\\n' }) + '\\n'
); );
} }
if (process.argv[2] === '--version' || process.argv[2] === '-v') { if (cliArgs.includes('--version') || cliArgs.includes('-v')) {
process.stdout.write(process.env.CCS_TEST_CODEX_VERSION || 'codex-cli 0.118.0-alpha.3'); process.stdout.write(process.env.CCS_TEST_CODEX_VERSION || 'codex-cli 0.118.0-alpha.3');
process.exit(0); process.exit(0);
} }
if (process.argv[2] === '--help' || process.argv[2] === '-h') { if (cliArgs.includes('--help') || cliArgs.includes('-h')) {
process.stdout.write( process.stdout.write(
process.env.CCS_TEST_CODEX_HELP || process.env.CCS_TEST_CODEX_HELP ||
' -c, --config <key=value>\\n -p, --profile <CONFIG_PROFILE>\\n' ' -c, --config <key=value>\\n -p, --profile <CONFIG_PROFILE>\\n'
@@ -244,10 +260,10 @@ process.exit(0);
]); ]);
}); });
it('fails fast when native Codex reasoning overrides need unsupported --config support', () => { it('keeps ccsxp pinned to native Codex even when a user passes another --target override', () => {
if (process.platform === 'win32') return; if (process.platform === 'win32') return;
const result = runCcs(['default', '--target', 'codex', '--effort', 'high', 'fix failing tests'], { const result = runCcsxpAlias(['--target', 'claude', '--version'], {
...process.env, ...process.env,
CI: '1', CI: '1',
NO_COLOR: '1', NO_COLOR: '1',
@@ -255,9 +271,48 @@ process.exit(0);
CCS_CODEX_PATH: fakeCodexPath, CCS_CODEX_PATH: fakeCodexPath,
CCS_TEST_CODEX_ARGS_OUT: codexArgsLogPath, CCS_TEST_CODEX_ARGS_OUT: codexArgsLogPath,
CCS_TEST_CODEX_VERSION: 'codex-cli 9.9.9-test', CCS_TEST_CODEX_VERSION: 'codex-cli 9.9.9-test',
CCS_TEST_CODEX_HELP: ' -p, --profile <CONFIG_PROFILE>\\n',
}); });
expect(result.status).toBe(0);
expect(result.stdout).toContain('codex-cli 9.9.9-test');
expect(readLoggedCodexCalls(codexArgsLogPath)).toEqual([['--version']]);
});
it('passes ccs codex --target codex --version through to the native Codex binary', () => {
if (process.platform === 'win32') return;
const result = runCcs(['codex', '--target', 'codex', '--version'], {
...process.env,
CI: '1',
NO_COLOR: '1',
CCS_HOME: tmpHome,
CCS_CODEX_PATH: fakeCodexPath,
CCS_TEST_CODEX_ARGS_OUT: codexArgsLogPath,
CCS_TEST_CODEX_VERSION: 'codex-cli 9.9.9-test',
});
expect(result.status).toBe(0);
expect(result.stdout).toContain('codex-cli 9.9.9-test');
expect(readLoggedCodexCalls(codexArgsLogPath)).toEqual([['--version']]);
});
it('fails fast when native Codex reasoning overrides need unsupported --config support', () => {
if (process.platform === 'win32') return;
const result = runCcs(
['default', '--target', 'codex', '--effort', 'high', 'fix failing tests'],
{
...process.env,
CI: '1',
NO_COLOR: '1',
CCS_HOME: tmpHome,
CCS_CODEX_PATH: fakeCodexPath,
CCS_TEST_CODEX_ARGS_OUT: codexArgsLogPath,
CCS_TEST_CODEX_VERSION: 'codex-cli 9.9.9-test',
CCS_TEST_CODEX_HELP: ' -p, --profile <CONFIG_PROFILE>\\n',
}
);
expect(result.status).toBe(1); expect(result.status).toBe(1);
expect(result.stderr).toContain('Codex CLI (codex-cli 9.9.9-test)'); expect(result.stderr).toContain('Codex CLI (codex-cli 9.9.9-test)');
expect(result.stderr).toContain('does not advertise --config overrides'); expect(result.stderr).toContain('does not advertise --config overrides');