feat: add max_claude_code_version setting and disable auto-upgrade env var

Add maximum Claude Code version limit to complement the existing minimum
version check. Refactor the version cache from single-value to unified
bounds struct (min+max) with a single atomic.Value and singleflight group.

- Backend: new constant, struct field, cache refactor, validation (semver
  format + cross-validation max >= min), gateway enforcement, audit diff
- Frontend: settings UI input, TypeScript types, zh/en i18n
- Add CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 to all Claude Code
  tutorials on /keys page (unix/cmd/powershell/vscode settings.json)
This commit is contained in:
shaw
2026-03-20 09:10:01 +08:00
parent 0236b97d49
commit 01d8286bd9
11 changed files with 130 additions and 49 deletions

View File

@@ -81,6 +81,7 @@ export interface SystemSettings {
// Claude Code version check
min_claude_code_version: string
max_claude_code_version: string
// 分组隔离
allow_ungrouped_key_scheduling: boolean
@@ -137,6 +138,7 @@ export interface UpdateSettingsRequest {
ops_query_mode_default?: 'auto' | 'raw' | 'preagg' | string
ops_metrics_interval_seconds?: number
min_claude_code_version?: string
max_claude_code_version?: string
allow_ungrouped_key_scheduling?: boolean
}

View File

@@ -441,17 +441,20 @@ function generateAnthropicFiles(baseUrl: string, apiKey: string): FileConfig[] {
case 'unix':
path = 'Terminal'
content = `export ANTHROPIC_BASE_URL="${baseUrl}"
export ANTHROPIC_AUTH_TOKEN="${apiKey}"`
export ANTHROPIC_AUTH_TOKEN="${apiKey}"
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1`
break
case 'cmd':
path = 'Command Prompt'
content = `set ANTHROPIC_BASE_URL=${baseUrl}
set ANTHROPIC_AUTH_TOKEN=${apiKey}`
set ANTHROPIC_AUTH_TOKEN=${apiKey}
set CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1`
break
case 'powershell':
path = 'PowerShell'
content = `$env:ANTHROPIC_BASE_URL="${baseUrl}"
$env:ANTHROPIC_AUTH_TOKEN="${apiKey}"`
$env:ANTHROPIC_AUTH_TOKEN="${apiKey}"
$env:CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1`
break
default:
path = 'Terminal'
@@ -466,6 +469,7 @@ $env:ANTHROPIC_AUTH_TOKEN="${apiKey}"`
"env": {
"ANTHROPIC_BASE_URL": "${baseUrl}",
"ANTHROPIC_AUTH_TOKEN": "${apiKey}",
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
"CLAUDE_CODE_ATTRIBUTION_HEADER": "0"
}
}`

View File

@@ -4119,7 +4119,11 @@ export default {
minVersion: 'Minimum Version',
minVersionPlaceholder: 'e.g. 2.1.63',
minVersionHint:
'Reject Claude Code clients below this version (semver format). Leave empty to disable version check.'
'Reject Claude Code clients below this version (semver format). Leave empty to disable version check.',
maxVersion: 'Maximum Version',
maxVersionPlaceholder: 'e.g. 2.5.0',
maxVersionHint:
'Reject Claude Code clients above this version (semver format). Leave empty to allow any version.'
},
scheduling: {
title: 'Gateway Scheduling Settings',

View File

@@ -4283,7 +4283,10 @@ export default {
description: '控制 Claude Code 客户端访问要求',
minVersion: '最低版本号',
minVersionPlaceholder: '例如 2.1.63',
minVersionHint: '拒绝低于此版本的 Claude Code 客户端请求semver 格式)。留空则不检查版本。'
minVersionHint: '拒绝低于此版本的 Claude Code 客户端请求semver 格式)。留空则不检查版本。',
maxVersion: '最高版本号',
maxVersionPlaceholder: '例如 2.5.0',
maxVersionHint: '拒绝高于此版本的 Claude Code 客户端请求semver 格式)。留空则不限制最高版本。'
},
scheduling: {
title: '网关调度设置',

View File

@@ -1127,6 +1127,20 @@
{{ t('admin.settings.claudeCode.minVersionHint') }}
</p>
</div>
<div class="mt-4">
<label class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300">
{{ t('admin.settings.claudeCode.maxVersion') }}
</label>
<input
v-model="form.max_claude_code_version"
type="text"
class="input max-w-xs font-mono text-sm"
:placeholder="t('admin.settings.claudeCode.maxVersionPlaceholder')"
/>
<p class="mt-1.5 text-xs text-gray-500 dark:text-gray-400">
{{ t('admin.settings.claudeCode.maxVersionHint') }}
</p>
</div>
</div>
</div>
@@ -1967,6 +1981,7 @@ const form = reactive<SettingsForm>({
ops_metrics_interval_seconds: 60,
// Claude Code version check
min_claude_code_version: '',
max_claude_code_version: '',
// 分组隔离
allow_ungrouped_key_scheduling: false
})
@@ -2232,6 +2247,7 @@ async function saveSettings() {
enable_identity_patch: form.enable_identity_patch,
identity_patch_prompt: form.identity_patch_prompt,
min_claude_code_version: form.min_claude_code_version,
max_claude_code_version: form.max_claude_code_version,
allow_ungrouped_key_scheduling: form.allow_ungrouped_key_scheduling
}
const updated = await adminAPI.settings.updateSettings(payload)