mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-13 22:15:33 +00:00
Merge remote-tracking branch 'origin/dev' into kai/review/pr-1655-retry-followup
This commit is contained in:
commit
2d909a162f
43 files changed
+953
-218
No files matched your search
@@ -648,7 +648,7 @@ function Test-Category6-Integration {
|
||||
|
||||
$Output = & $CcsPath --version 2>&1 | Out-String
|
||||
|
||||
$ShowsVersion = $Output -match "CCS \(Claude Code Switch\) version"
|
||||
$ShowsVersion = $Output -match "CCS \(Claude Codex Switch\) v\d+\.\d+\.\d+"
|
||||
|
||||
if ($ShowsVersion) {
|
||||
$Duration = ((Get-Date) - $TestStart).TotalMilliseconds
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('integration: special commands', () => {
|
||||
|
||||
it('shows version with --version', () => {
|
||||
const output = execSync(buildCliCommand('--version'), { encoding: 'utf8' });
|
||||
assert(output.includes('CCS (Claude Code Switch)'));
|
||||
assert(output.includes('CCS (Claude Codex Switch)'));
|
||||
assert(/v\d+\.\d+\.\d+/.test(output));
|
||||
});
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
importApiProfileBundle,
|
||||
registerApiProfileOrphans,
|
||||
} from '../../../src/api/services/profile-lifecycle-service';
|
||||
import { validateApiProfileSettingsPayload } from '../../../src/api/services/profile-lifecycle-validation';
|
||||
import { createApiProfile } from '../../../src/api/services/profile-writer';
|
||||
import {
|
||||
loadConfigSafe,
|
||||
@@ -69,6 +70,38 @@ describe('profile lifecycle service', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('accepts ANTHROPIC_DEFAULT_FABLE_MODEL as a supported model mapping', () => {
|
||||
const validation = validateApiProfileSettingsPayload({
|
||||
env: {
|
||||
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8317/api/provider/codex',
|
||||
ANTHROPIC_AUTH_TOKEN: 'token',
|
||||
ANTHROPIC_DEFAULT_FABLE_MODEL: 'gpt-5.4-mini',
|
||||
},
|
||||
});
|
||||
|
||||
expect(validation.valid).toBe(true);
|
||||
expect(validation.issues).toEqual([]);
|
||||
});
|
||||
|
||||
it('enforces the provider denylist for ANTHROPIC_DEFAULT_FABLE_MODEL', () => {
|
||||
const validation = validateApiProfileSettingsPayload({
|
||||
env: {
|
||||
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8317/api/provider/agy',
|
||||
ANTHROPIC_AUTH_TOKEN: 'token',
|
||||
ANTHROPIC_DEFAULT_FABLE_MODEL: 'claude-sonnet-4.5',
|
||||
},
|
||||
});
|
||||
|
||||
expect(validation.valid).toBe(false);
|
||||
expect(validation.issues).toContainEqual(
|
||||
expect.objectContaining({
|
||||
level: 'error',
|
||||
code: 'model_denylisted',
|
||||
field: 'env.ANTHROPIC_DEFAULT_FABLE_MODEL',
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('discovers grandfathered xai/grok orphans while skipping other reserved names', async () => {
|
||||
const ccsDir = path.join(tempHome, '.ccs');
|
||||
fs.mkdirSync(ccsDir, { recursive: true });
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, it } from 'bun:test';
|
||||
|
||||
import {
|
||||
ANTHROPIC_MODEL_ENV_KEYS,
|
||||
isAnthropicModelEnvKey,
|
||||
} from '../../../src/shared/extended-context-utils';
|
||||
|
||||
describe('Anthropic model env keys', () => {
|
||||
it('includes all five tier mapping keys', () => {
|
||||
expect([...ANTHROPIC_MODEL_ENV_KEYS]).toEqual([
|
||||
'ANTHROPIC_MODEL',
|
||||
'ANTHROPIC_DEFAULT_OPUS_MODEL',
|
||||
'ANTHROPIC_DEFAULT_SONNET_MODEL',
|
||||
'ANTHROPIC_DEFAULT_HAIKU_MODEL',
|
||||
'ANTHROPIC_DEFAULT_FABLE_MODEL',
|
||||
]);
|
||||
});
|
||||
|
||||
it('recognizes the fable tier key like the other tiers', () => {
|
||||
expect(isAnthropicModelEnvKey('ANTHROPIC_DEFAULT_FABLE_MODEL')).toBe(true);
|
||||
expect(isAnthropicModelEnvKey('ANTHROPIC_DEFAULT_HAIKU_MODEL')).toBe(true);
|
||||
expect(isAnthropicModelEnvKey('ANTHROPIC_BASE_URL')).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -264,6 +264,7 @@ describe('CLAUDECODE environment stripping', () => {
|
||||
delete process.env.ANTHROPIC_DEFAULT_OPUS_MODEL;
|
||||
delete process.env.ANTHROPIC_DEFAULT_SONNET_MODEL;
|
||||
delete process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL;
|
||||
delete process.env.ANTHROPIC_DEFAULT_FABLE_MODEL;
|
||||
delete process.env.ANTHROPIC_SMALL_FAST_MODEL;
|
||||
delete process.env.CLAUDE_CODE_MAX_OUTPUT_TOKENS;
|
||||
|
||||
@@ -543,6 +544,7 @@ describe('CLAUDECODE environment stripping', () => {
|
||||
process.env.ANTHROPIC_API_KEY = 'parent-api-key';
|
||||
process.env.ANTHROPIC_MODEL = 'gpt-5.4';
|
||||
process.env.ANTHROPIC_DEFAULT_SONNET_MODEL = 'gpt-5.4';
|
||||
process.env.ANTHROPIC_DEFAULT_FABLE_MODEL = 'gpt-5.4-mini';
|
||||
|
||||
execClaude('claude', ['--help'], {
|
||||
CCS_PROFILE_TYPE: 'settings',
|
||||
@@ -570,10 +572,18 @@ describe('CLAUDECODE environment stripping', () => {
|
||||
call.args[1] === 'ANTHROPIC_MODEL' &&
|
||||
call.args[2] === 'gpt-5.4'
|
||||
);
|
||||
const fableModelCall = spawnSyncCalls.find(
|
||||
(call) =>
|
||||
call.command === 'tmux' &&
|
||||
call.args[0] === 'setenv' &&
|
||||
call.args[1] === 'ANTHROPIC_DEFAULT_FABLE_MODEL' &&
|
||||
call.args[2] === 'gpt-5.4-mini'
|
||||
);
|
||||
|
||||
expect(unsetBaseUrlCall).toBeDefined();
|
||||
expect(unsetAuthTokenCall).toBeDefined();
|
||||
expect(modelCall).toBeDefined();
|
||||
expect(fableModelCall).toBeDefined();
|
||||
});
|
||||
|
||||
it('headless executor spawn path strips CLAUDECODE before spawn', async () => {
|
||||
|
||||
Reference in new issue
Block a user