feat: share stale Codex translator path scanner

This commit is contained in:
Tam Nhu Tran committed 2026-05-22 12:10:54 -04:00
1 parent 604ef7be81
commit 46d73ae79f
5 files changed
+150 -51

No files matched your search

+5 -41
View File
@@ -18,6 +18,11 @@ import ProfileDetector from '../auth/profile-detector';
import { getClaudeConfigDir, getClaudeSettingsPath } from '../utils/claude-config-path';
import { extractOption, hasAnyFlag } from './arg-extractor';
import { resolveClaudeExtensionSetup } from '../shared/claude-extension-setup';
import {
CODEX_TRANSLATOR_URL_MARKER,
findCodexTranslatorUrlPaths,
formatSettingsPathList,
} from '../shared/stale-codex-translator-settings';
interface PersistCommandArgs {
profile?: string;
@@ -64,7 +69,6 @@ const PERSIST_LOCK_STALE_MS = 10000;
const PERSIST_LOCK_RETRIES = 5;
const PERSIST_LOCK_RETRY_MIN_MS = 100;
const PERSIST_LOCK_RETRY_MAX_MS = 500;
const CODEX_TRANSLATOR_URL_MARKER = '/api/provider/codex';
const NATIVE_CODEX_TARGETS = ['ccsxp', 'ccs codex --target codex'];
type PermissionMode = (typeof VALID_PERMISSION_MODES)[number];
@@ -521,38 +525,6 @@ function isSensitiveEnvKey(key: string): boolean {
);
}
function formatSettingsPathSegment(basePath: string, segment: string | number): string {
if (typeof segment === 'number') {
return `${basePath}[${segment}]`;
}
if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(segment)) {
return basePath ? `${basePath}.${segment}` : segment;
}
return `${basePath}[${JSON.stringify(segment)}]`;
}
function findCodexTranslatorUrlPaths(value: unknown, path = ''): string[] {
if (typeof value === 'string') {
return value.includes(CODEX_TRANSLATOR_URL_MARKER) ? [path || '(root)'] : [];
}
if (Array.isArray(value)) {
return value.flatMap((item, index) =>
findCodexTranslatorUrlPaths(item, formatSettingsPathSegment(path, index))
);
}
if (typeof value === 'object' && value !== null) {
return Object.entries(value).flatMap(([key, item]) =>
findCodexTranslatorUrlPaths(item, formatSettingsPathSegment(path, key))
);
}
return [];
}
function buildPersistReceipt(
existingEnv: Record<string, string>,
existingSettings: Record<string, unknown>,
@@ -611,14 +583,6 @@ function formatKeyList(keys: string[]): string {
return keys.length > 0 ? keys.join(', ') : 'none';
}
function formatSettingsPathList(paths: string[]): string {
const visiblePaths = paths.slice(0, 5);
const remainingCount = paths.length - visiblePaths.length;
return remainingCount > 0
? `${visiblePaths.join(', ')} (+${remainingCount} more)`
: visiblePaths.join(', ');
}
function printPersistReceipt(receipt: PersistReceipt): void {
console.log(subheader('Config Receipt'));
console.log(` Settings: ${getClaudeSettingsDisplayPath()}`);
+13 -10
View File
@@ -9,6 +9,11 @@ import { HealthCheck, IHealthChecker, createSpinner } from './types';
import { getClaudeConfigDir } from '../../utils/claude-config-path';
import { getCcsDir } from '../../config/config-loader-facade';
import {
CODEX_TRANSLATOR_URL_MARKER,
findCodexTranslatorUrlPaths,
formatSettingsPathList,
} from '../../shared/stale-codex-translator-settings';
const ora = createSpinner();
@@ -219,20 +224,18 @@ export class ClaudeSettingsChecker implements IHealthChecker {
// Validate JSON
try {
const content = fs.readFileSync(settingsPath, 'utf8');
const settings = JSON.parse(content) as {
env?: Record<string, unknown>;
};
const baseUrl =
settings.env && typeof settings.env.ANTHROPIC_BASE_URL === 'string'
? settings.env.ANTHROPIC_BASE_URL
: '';
if (baseUrl.includes('/api/provider/codex')) {
const settings = JSON.parse(content) as unknown;
const codexTranslatorUrlPaths = findCodexTranslatorUrlPaths(settings);
if (codexTranslatorUrlPaths.length > 0) {
const formattedPaths = formatSettingsPathList(codexTranslatorUrlPaths);
spinner.warn();
console.log(` ${warn(settingsName.padEnd(22))} Codex CLIProxy bridge persisted`);
console.log(
` ${warn(settingsName.padEnd(22))} Codex CLIProxy bridge persisted at ${formattedPaths}`
);
results.addCheck(
'Claude Settings',
'warning',
'Claude settings route Claude Code through the Codex CLIProxy translator',
`Claude settings route Claude Code through the Codex CLIProxy translator at ${formattedPaths} (${CODEX_TRANSLATOR_URL_MARKER})`,
'Run: ccs persist default --yes; use ccsxp or ccs codex --target codex for Codex'
);
return;
@@ -0,0 +1,41 @@
export const CODEX_TRANSLATOR_URL_MARKER = '/api/provider/codex';
function formatSettingsPathSegment(basePath: string, segment: string | number): string {
if (typeof segment === 'number') {
return `${basePath}[${segment}]`;
}
if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(segment)) {
return basePath ? `${basePath}.${segment}` : segment;
}
return `${basePath}[${JSON.stringify(segment)}]`;
}
export function findCodexTranslatorUrlPaths(value: unknown, path = ''): string[] {
if (typeof value === 'string') {
return value.includes(CODEX_TRANSLATOR_URL_MARKER) ? [path || '(root)'] : [];
}
if (Array.isArray(value)) {
return value.flatMap((item, index) =>
findCodexTranslatorUrlPaths(item, formatSettingsPathSegment(path, index))
);
}
if (typeof value === 'object' && value !== null) {
return Object.entries(value).flatMap(([key, item]) =>
findCodexTranslatorUrlPaths(item, formatSettingsPathSegment(path, key))
);
}
return [];
}
export function formatSettingsPathList(paths: string[]): string {
const visiblePaths = paths.slice(0, 5);
const remainingCount = paths.length - visiblePaths.length;
return remainingCount > 0
? `${visiblePaths.join(', ')} (+${remainingCount} more)`
: visiblePaths.join(', ');
}