Files
ccs/src/bin/ccsxp-runtime.ts
T
Tam Nhu Tran 8c604a040f feat(codex-auth): wire ccsx bin router + ccsxp scope notice
Upgrades the previously-stub ccsx binary entry (src/bin/codex-runtime.ts)
into an argv router: `ccsx auth <cmd>` dispatches to the Phase 2 router;
any other argv resolves the active codex-auth profile and spawns codex
with CODEX_HOME pointed at the profile dir.

- resolve-active-profile: sync, hot-path-safe (<5ms), reads YAML
  registry via Phase 1 helpers; precedence is CODEX_HOME (explicit)
  > CCS_CODEX_PROFILE (env) > registry default > null (legacy
  ~/.codex fallback); fails open on any error (silent for missing
  registry, stderr warn for corrupt/missing-profile)
- codex-runtime-router: extracted main() for testability; entry
  script is a thin 3-line wrapper; returns -1 sentinel for the
  CCS branch so the spawn lifecycle isn't terminated
- ccsxp-runtime: H5 defensive stderr notice when CCS_CODEX_PROFILE
  is set, surfacing the boundary between codex-auth (native codex)
  and ccsxp (cliproxy pool) without changing functional behavior;
  CLIProxyAPI does not read CODEX_HOME so no pool contamination
  possible
- 14 unit tests (8 resolver + 6 router); ccsxp regression suite
  (5 tests) untouched and still green
2026-05-17 14:45:13 -04:00

111 lines
3.5 KiB
TypeScript

const os = require('os');
const path = require('path');
const { CCSXP_CLIPROXY_SHORTCUT_ENV } = require('../targets/codex-cliproxy-provider-config');
const { stripTargetFlag } = require('../targets/target-resolver');
const { expandPath } = require('../utils/helpers');
const { fail } = require('../utils/ui');
process.env.CCS_INTERNAL_ENTRY_TARGET = 'codex';
process.env[CCSXP_CLIPROXY_SHORTCUT_ENV] = '1';
const CCSXP_CLIPROXY_OVERRIDE = 'model_provider="cliproxy"';
const DISALLOWED_CCSXP_CONFIG_KEY_REGEX =
/^(model_provider|local_provider|profile)\s*=|^model_providers\./i;
function isDisallowedCcsxpConfigOverride(value: unknown) {
return typeof value === 'string' && DISALLOWED_CCSXP_CONFIG_KEY_REGEX.test(value.trim());
}
function findDisallowedCcsxpFlags(args: string[]) {
const disallowed = new Set();
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
if (arg === '--') {
break;
}
if (arg === '-p' || arg === '--profile' || arg.startsWith('--profile=')) {
disallowed.add('--profile/-p');
continue;
}
if (arg === '--oss') {
disallowed.add('--oss');
continue;
}
if (arg === '--local-provider' || arg.startsWith('--local-provider=')) {
disallowed.add('--local-provider');
continue;
}
if (arg === '-c' || arg === '--config') {
const value = args[index + 1];
if (isDisallowedCcsxpConfigOverride(value)) {
disallowed.add('--config/-c provider override');
}
index += 1;
continue;
}
if (arg.startsWith('--config=')) {
const value = arg.slice('--config='.length);
if (isDisallowedCcsxpConfigOverride(value)) {
disallowed.add('--config/-c provider override');
}
}
}
return [...disallowed];
}
function resolveCcsxpCodexHome() {
const configuredHome = process.env.CCSXP_CODEX_HOME?.trim();
if (configuredHome) {
return path.resolve(expandPath(configuredHome));
}
return path.join(os.homedir(), '.codex');
}
// H5: CCS_CODEX_PROFILE is ignored by ccsxp. The ccsx auth profile system
// (src/codex-auth/) is intentionally NOT consulted here — ccsxp serves the
// cliproxy round-robin pool, not per-user-account profiles. Emit a one-line
// notice so users who set CCS_CODEX_PROFILE in their shell don't get confused
// when ccsxp silently ignores it and overwrites CODEX_HOME below.
if (process.env.CCS_CODEX_PROFILE) {
process.stderr.write(
"[i] CCS_CODEX_PROFILE is ignored by ccsxp; profile applies to native 'codex' only.\n"
);
}
process.env.CODEX_HOME = resolveCcsxpCodexHome();
// ccsxp is the Codex + cliproxy shortcut. Keep the native Codex history root,
// strip conflicting target overrides, and prepend the native cliproxy provider
// override so the runtime stays as close to plain Codex as possible.
const forwardedArgs = (() => {
try {
const disallowedFlags = findDisallowedCcsxpFlags(process.argv.slice(2));
if (disallowedFlags.length > 0) {
throw new Error(
`ccsxp does not allow ${disallowedFlags.join(', ')} because the native cliproxy shortcut owns provider selection. Remove native Codex provider-selection flags and retry.`
);
}
return stripTargetFlag(process.argv.slice(2));
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
console.error(fail(message));
process.exit(1);
}
})();
process.argv.splice(
2,
process.argv.length - 2,
'--config',
CCSXP_CLIPROXY_OVERRIDE,
...forwardedArgs
);
require('../ccs');