mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-10 04:19:29 +00:00
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
111 lines
3.5 KiB
TypeScript
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');
|