mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-14 12:16:38 +00:00
fix(codex): harden native alias launches
- pass ccsx help/version flags straight through to native Codex - strip parent Codex session env before nested launches - avoid eager version/help probes unless config override detection is needed
This commit is contained in:
1 parent
bcbf780f82
commit
f47ab484f3
6 files changed
+182
-29
No files matched your search
+47
@@ -95,6 +95,7 @@ interface RuntimeReasoningResolution {
|
||||
}
|
||||
|
||||
const CODEX_RUNTIME_REASONING_LEVELS = new Set(['minimal', 'low', 'medium', 'high', 'xhigh']);
|
||||
const CODEX_NATIVE_PASSTHROUGH_FLAGS = new Set(['--help', '-h', '--version', '-v']);
|
||||
|
||||
/**
|
||||
* Smart profile detection
|
||||
@@ -239,6 +240,47 @@ function resolveNativeClaudeLaunchArgs(
|
||||
return buildOfficialChannelsArgs(args, plan.appliedChannels, plan.wantsPermissionBypass);
|
||||
}
|
||||
|
||||
function shouldPassthroughNativeCodexFlagCommand(args: string[]): boolean {
|
||||
const targetArgs = stripTargetFlag(args);
|
||||
if (targetArgs.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
resolveTargetType(args) === 'codex' && CODEX_NATIVE_PASSTHROUGH_FLAGS.has(targetArgs[0] || '')
|
||||
);
|
||||
}
|
||||
|
||||
function execNativeCodexFlagCommand(args: string[]): void {
|
||||
const adapter = getTarget('codex');
|
||||
if (!adapter) {
|
||||
console.error(fail('Target adapter not found for "codex"'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const binaryInfo = adapter.detectBinary();
|
||||
if (!binaryInfo) {
|
||||
console.error(fail('Codex CLI not found.'));
|
||||
console.error(info('Install a recent @openai/codex build, then retry.'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const targetArgs = stripTargetFlag(args);
|
||||
const creds: TargetCredentials = {
|
||||
profile: 'default',
|
||||
baseUrl: '',
|
||||
apiKey: '',
|
||||
};
|
||||
|
||||
const builtArgs = adapter.buildArgs('default', targetArgs, {
|
||||
creds,
|
||||
profileType: 'default',
|
||||
binaryInfo,
|
||||
});
|
||||
const targetEnv = adapter.buildEnv(creds, 'default');
|
||||
adapter.exec(builtArgs, targetEnv, { binaryInfo });
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
// Register target adapters
|
||||
registerTarget(new ClaudeAdapter());
|
||||
@@ -315,6 +357,11 @@ async function main(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldPassthroughNativeCodexFlagCommand(args)) {
|
||||
execNativeCodexFlagCommand(args);
|
||||
return;
|
||||
}
|
||||
|
||||
const firstArg = args[0];
|
||||
|
||||
// Trigger update check early for ALL commands except version/help/update
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as fs from 'fs';
|
||||
import type { ProfileType } from '../types/profile';
|
||||
import { runCleanup } from '../errors';
|
||||
import { wireChildProcessSignals } from '../utils/signal-forwarder';
|
||||
import { escapeShellArg, stripAnthropicEnv } from '../utils/shell-executor';
|
||||
import { escapeShellArg, stripAnthropicEnv, stripCodexSessionEnv } from '../utils/shell-executor';
|
||||
import type {
|
||||
TargetAdapter,
|
||||
TargetBinaryInfo,
|
||||
@@ -76,7 +76,7 @@ export class CodexAdapter implements TargetAdapter {
|
||||
readonly displayName = 'Codex CLI';
|
||||
|
||||
detectBinary(): TargetBinaryInfo | null {
|
||||
return getCodexBinaryInfo();
|
||||
return getCodexBinaryInfo({ includeVersion: false, includeFeatures: false });
|
||||
}
|
||||
|
||||
async prepareCredentials(_creds: TargetCredentials): Promise<void> {
|
||||
@@ -148,7 +148,9 @@ export class CodexAdapter implements TargetAdapter {
|
||||
}
|
||||
|
||||
buildEnv(creds: TargetCredentials, profileType: ProfileType): NodeJS.ProcessEnv {
|
||||
const env: NodeJS.ProcessEnv = { ...stripAnthropicEnv(process.env) };
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...stripCodexSessionEnv(stripAnthropicEnv(process.env)),
|
||||
};
|
||||
delete env[CODEX_RUNTIME_ENV_KEY];
|
||||
if (profileType !== 'default') {
|
||||
if (!creds.apiKey?.trim()) {
|
||||
|
||||
@@ -118,7 +118,10 @@ export function detectCodexCli(): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getCodexBinaryInfo(): TargetBinaryInfo | null {
|
||||
export function getCodexBinaryInfo(options?: {
|
||||
includeVersion?: boolean;
|
||||
includeFeatures?: boolean;
|
||||
}): TargetBinaryInfo | null {
|
||||
const codexPath = detectCodexCli();
|
||||
if (!codexPath) return null;
|
||||
|
||||
@@ -126,13 +129,21 @@ export function getCodexBinaryInfo(): TargetBinaryInfo | null {
|
||||
return {
|
||||
path: codexPath,
|
||||
needsShell: isWindows && /\.(cmd|bat|ps1)$/i.test(codexPath),
|
||||
version: readCodexVersion(codexPath),
|
||||
features: detectCodexFeatures(codexPath),
|
||||
version: options?.includeVersion === false ? undefined : readCodexVersion(codexPath),
|
||||
features: options?.includeFeatures === false ? undefined : detectCodexFeatures(codexPath),
|
||||
};
|
||||
}
|
||||
|
||||
export function codexBinarySupportsConfigOverrides(
|
||||
binaryInfo: TargetBinaryInfo | null | undefined
|
||||
): boolean {
|
||||
return Boolean(binaryInfo?.features?.includes(CODEX_CONFIG_OVERRIDE_FEATURE));
|
||||
if (!binaryInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (binaryInfo.features) {
|
||||
return binaryInfo.features.includes(CODEX_CONFIG_OVERRIDE_FEATURE);
|
||||
}
|
||||
|
||||
return detectCodexFeatures(binaryInfo.path).includes(CODEX_CONFIG_OVERRIDE_FEATURE);
|
||||
}
|
||||
@@ -42,6 +42,25 @@ export function stripClaudeCodeEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip Codex session-scoped env vars before launching a nested Codex process.
|
||||
*
|
||||
* Keep real user config such as CODEX_HOME intact. Only remove the known
|
||||
* session/runtime metadata exported by the current Codex host process.
|
||||
*/
|
||||
export function stripCodexSessionEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
|
||||
const sessionKeys = new Set(['CODEX_CI', 'CODEX_MANAGED_BY_BUN', 'CODEX_THREAD_ID']);
|
||||
const result: NodeJS.ProcessEnv = {};
|
||||
for (const key of Object.keys(env)) {
|
||||
const upperKey = key.toUpperCase();
|
||||
if (sessionKeys.has(upperKey)) {
|
||||
continue;
|
||||
}
|
||||
result[key] = env[key];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve CCS-managed environment overrides for Claude launch.
|
||||
* - preferences.auto_update: false -> DISABLE_AUTOUPDATER=1
|
||||
|
||||
Reference in new issue
Block a user