fix(settings-profile): pass selective Anthropic env stripping to Claude launches

This commit is contained in:
Wooseong Kim
2026-04-22 14:08:37 +09:00
parent 9ae85b82c1
commit 5881a505d9
2 changed files with 59 additions and 3 deletions
+15 -3
View File
@@ -1359,8 +1359,20 @@ async function main(): Promise<void> {
console.error(info(`Global env: ${envNames}`));
}
// Explicitly inject effective settings env vars so stale ANTHROPIC_*
// values from prior sessions cannot leak into the active profile.
// For Claude target launches that already pass `--settings`, keep runtime
// env limited to CCS-managed flags so nested Team/subagent sessions do not
// inherit profile-specific ANTHROPIC_* routing from the parent process.
const claudeRuntimeEnvVars: NodeJS.ProcessEnv = {
...globalEnv,
...(inheritedClaudeConfigDir ? { CLAUDE_CONFIG_DIR: inheritedClaudeConfigDir } : {}),
...webSearchEnv,
...imageAnalysisEnv,
...(browserRuntimeEnv || {}),
CCS_PROFILE_TYPE: 'settings',
CCS_STRIP_INHERITED_ANTHROPIC_ENV: '1',
};
// Non-Claude targets still need effective credentials injected directly.
const envVars: NodeJS.ProcessEnv = {
...globalEnv,
...settingsEnv,
@@ -1472,7 +1484,7 @@ async function main(): Promise<void> {
settingsPath: expandedSettingsPath,
});
execClaude(claudeCli, launchArgs, { ...envVars, ...traceEnv });
execClaude(claudeCli, launchArgs, { ...claudeRuntimeEnvVars, ...traceEnv });
} else if (profileInfo.type === 'account') {
// NEW FLOW: Account-based profile (work, personal)
// All platforms: Use instance isolation with CLAUDE_CONFIG_DIR
@@ -135,6 +135,12 @@ printf "%s\n" "$@" > "${claudeArgsLogPath}"
printf "port=%s\n" "$CCS_BROWSER_DEVTOOLS_PORT"
printf "httpUrl=%s\n" "$CCS_BROWSER_DEVTOOLS_HTTP_URL"
printf "wsUrl=%s\n" "$CCS_BROWSER_DEVTOOLS_WS_URL"
printf "stripAnthropic=%s\n" "$CCS_STRIP_INHERITED_ANTHROPIC_ENV"
printf "anthropicBaseUrl=%s\n" "$ANTHROPIC_BASE_URL"
printf "anthropicAuthToken=%s\n" "$ANTHROPIC_AUTH_TOKEN"
printf "anthropicApiKey=%s\n" "$ANTHROPIC_API_KEY"
printf "anthropicModel=%s\n" "$ANTHROPIC_MODEL"
printf "anthropicSonnet=%s\n" "$ANTHROPIC_DEFAULT_SONNET_MODEL"
} > "${claudeEnvLogPath}"
exit 0
`,
@@ -179,6 +185,44 @@ exit 0
expect(fs.existsSync(claudeArgsLogPath)).toBe(true);
});
it('passes selective Anthropic env stripping to settings-profile Claude launches while preserving model defaults', () => {
if (process.platform === 'win32') return;
fs.writeFileSync(
settingsPath,
JSON.stringify(
{
env: {
ANTHROPIC_BASE_URL: 'https://api.z.ai/api/anthropic',
ANTHROPIC_AUTH_TOKEN: 'profile-token',
ANTHROPIC_MODEL: 'gpt-5.4',
ANTHROPIC_DEFAULT_SONNET_MODEL: 'gpt-5.4',
},
},
null,
2
) + '\n'
);
const result = runCcs(['glm', 'smoke'], {
...baseEnv,
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8317/api/provider/codex',
ANTHROPIC_AUTH_TOKEN: 'parent-routing-token',
ANTHROPIC_API_KEY: 'parent-api-key',
ANTHROPIC_MODEL: 'gpt-5.4',
ANTHROPIC_DEFAULT_SONNET_MODEL: 'gpt-5.4',
});
expect(result.status).toBe(0);
const launchedEnv = fs.readFileSync(claudeEnvLogPath, 'utf8');
expect(launchedEnv).toContain('stripAnthropic=1');
expect(launchedEnv).toContain('anthropicBaseUrl=');
expect(launchedEnv).toContain('anthropicAuthToken=');
expect(launchedEnv).toContain('anthropicApiKey=');
expect(launchedEnv).toContain('anthropicModel=gpt-5.4');
expect(launchedEnv).toContain('anthropicSonnet=gpt-5.4');
});
it('does not auto-enable browser reuse for settings-profile launches from env overrides alone', async () => {
if (process.platform === 'win32') return;