mirror of
https://github.com/NanmiCoder/claude-code-haha.git
synced 2026-10-10 20:03:13 +08:00
fix(desktop): warn on proxy-only settings takeover #1219
This commit is contained in:
@@ -246,6 +246,7 @@ describe('Settings > General tab', () => {
|
||||
traceCapture: { enabled: true, storageDir: '/Users/test/.claude/cc-haha/traces' },
|
||||
chatSendBehavior: 'enter',
|
||||
responseLanguage: '',
|
||||
proxyManagedSettingsWarning: false,
|
||||
uiZoom: 1,
|
||||
webSearch: { mode: 'auto', tavilyApiKey: '', braveApiKey: '' },
|
||||
network: {
|
||||
@@ -1710,6 +1711,17 @@ describe('Settings > General tab', () => {
|
||||
expect(screen.getByText('MCP')).toBeInTheDocument()
|
||||
expect(screen.getByText('Plugins')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('warns when the user settings contain only a proxy-managed placeholder', async () => {
|
||||
useSettingsStore.setState({ proxyManagedSettingsWarning: true })
|
||||
|
||||
render(<Settings />)
|
||||
fireEvent.click(screen.getByRole('button', { name: 'General' }))
|
||||
|
||||
expect(await screen.findByRole('alert')).toHaveTextContent(
|
||||
'Your user settings contain only a PROXY_MANAGED proxy placeholder',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Settings > Providers tab', () => {
|
||||
|
||||
@@ -1443,6 +1443,7 @@ Row 9, all 8 cells: continuing from straight down, turning left through lower-le
|
||||
|
||||
// Settings > General
|
||||
'settings.general.appearanceTitle': 'Appearance',
|
||||
'settings.general.proxyManagedSettingsWarning': 'Your user settings contain only a PROXY_MANAGED proxy placeholder, so another proxy tool may have replaced the remaining settings. If this was not intentional, disable CC Switch routing takeover and restore settings.json from a backup. Otherwise, you can ignore this notice.',
|
||||
'settings.general.appearanceDescription': 'Switch between the six paper and ink palettes.',
|
||||
'settings.general.appearance.paper': 'Paper',
|
||||
'settings.general.appearance.warmClassic': 'Warm Classic',
|
||||
|
||||
@@ -1445,6 +1445,7 @@ export const jp: Record<TranslationKey, string> = {
|
||||
|
||||
// Settings > General
|
||||
'settings.general.appearanceTitle': '外観',
|
||||
'settings.general.proxyManagedSettingsWarning': 'ユーザー設定が PROXY_MANAGED プロキシのプレースホルダーだけになっており、他の設定がプロキシツールに上書きされた可能性があります。意図した設定でなければ、CC Switch のルーティング引き継ぎを無効にして、バックアップから settings.json を復元してください。意図した設定なら、この通知は無視できます。',
|
||||
'settings.general.appearanceDescription': '紙と墨の 6 つの配色を切り替えます。',
|
||||
'settings.general.appearance.paper': '紙墨',
|
||||
'settings.general.appearance.warmClassic': 'クラシックウォーム',
|
||||
|
||||
@@ -1445,6 +1445,7 @@ export const kr: Record<TranslationKey, string> = {
|
||||
|
||||
// Settings > General
|
||||
'settings.general.appearanceTitle': '모양',
|
||||
'settings.general.proxyManagedSettingsWarning': '사용자 설정에 PROXY_MANAGED 프록시 자리표시자만 남아 있어 다른 설정이 프록시 도구에 의해 덮어쓰였을 수 있습니다. 의도한 설정이 아니라면 CC Switch 라우팅 인계를 끄고 백업에서 settings.json을 복원하세요. 직접 설정한 경우에는 이 알림을 무시해도 됩니다.',
|
||||
'settings.general.appearanceDescription': '종이와 먹의 여섯 가지 배색을 전환합니다.',
|
||||
'settings.general.appearance.paper': '지묵',
|
||||
'settings.general.appearance.warmClassic': '따뜻한 클래식',
|
||||
|
||||
@@ -1444,6 +1444,7 @@ export const zh: Record<TranslationKey, string> = {
|
||||
|
||||
// Settings > General
|
||||
'settings.general.appearanceTitle': '配色主題',
|
||||
'settings.general.proxyManagedSettingsWarning': '偵測到使用者設定只剩 PROXY_MANAGED 代理占位資訊,其他設定可能被代理工具覆寫。若這不是你的主動設定,請先關閉 CC Switch 路由接管並從備份還原 settings.json;主動使用此設定可忽略。',
|
||||
'settings.general.appearanceDescription': '在紙、墨、印六套配色之間切換。',
|
||||
'settings.general.appearance.paper': '紙墨',
|
||||
'settings.general.appearance.warmClassic': '經典暖色',
|
||||
|
||||
@@ -1444,6 +1444,7 @@ export const zh: Record<TranslationKey, string> = {
|
||||
|
||||
// Settings > General
|
||||
'settings.general.appearanceTitle': '配色主题',
|
||||
'settings.general.proxyManagedSettingsWarning': '检测到用户配置仅剩 PROXY_MANAGED 代理占位信息,其他设置可能被代理工具覆盖。若这不是你的主动配置,请先关闭 CC Switch 路由接管并从备份恢复 settings.json;主动使用该配置可忽略。',
|
||||
'settings.general.appearanceDescription': '在纸、墨、印六套配色之间切换。',
|
||||
'settings.general.appearance.paper': '纸墨',
|
||||
'settings.general.appearance.warmClassic': '经典暖色',
|
||||
|
||||
@@ -88,6 +88,7 @@ export function GeneralSettings() {
|
||||
setAppMode: setAppModeAction,
|
||||
uiZoom,
|
||||
setUiZoom,
|
||||
proxyManagedSettingsWarning,
|
||||
} = useSettingsStore()
|
||||
// Read the theme from the store that owns it. settingsStore keeps a copy for
|
||||
// its own consumers, but that copy is only refreshed on an explicit setTheme
|
||||
@@ -616,6 +617,14 @@ export function GeneralSettings() {
|
||||
|
||||
return (
|
||||
<div className="max-w-xl">
|
||||
{proxyManagedSettingsWarning && (
|
||||
<div
|
||||
role="alert"
|
||||
className="mb-5 rounded-[var(--radius-lg)] border border-[var(--color-warning)] bg-[var(--color-warning-container)] px-3 py-2 text-xs leading-5 text-[var(--color-on-warning-container)]"
|
||||
>
|
||||
{t('settings.general.proxyManagedSettingsWarning')}
|
||||
</div>
|
||||
)}
|
||||
{/* No page header here on purpose: the only title it could carry is the nav
|
||||
label verbatim, with no description to add. The pane opens on its first
|
||||
section instead. */}
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
type ThemeMode,
|
||||
type UpdateProxyMode,
|
||||
type UpdateProxySettings,
|
||||
type UserSettings,
|
||||
type WebSearchSettings,
|
||||
} from '../types/settings'
|
||||
import type { TraceCaptureSettings } from '../types/trace'
|
||||
@@ -85,6 +86,7 @@ type SettingsStore = {
|
||||
uiZoom: number
|
||||
isLoading: boolean
|
||||
error: string | null
|
||||
proxyManagedSettingsWarning: boolean
|
||||
|
||||
appMode: AppModeConfig
|
||||
appModeRequiresRestart: boolean
|
||||
@@ -210,6 +212,7 @@ export const useSettingsStore = create<SettingsStore>((set, get) => ({
|
||||
uiZoom: readStoredAppZoomLevel(),
|
||||
isLoading: false,
|
||||
error: null,
|
||||
proxyManagedSettingsWarning: false,
|
||||
|
||||
appMode: {
|
||||
mode: 'default',
|
||||
@@ -274,6 +277,7 @@ export const useSettingsStore = create<SettingsStore>((set, get) => ({
|
||||
h5AccessDiagnostics: h5AccessResult.diagnostics,
|
||||
h5AccessError: h5AccessResult.error,
|
||||
responseLanguage: typeof userSettings.language === 'string' ? userSettings.language : '',
|
||||
proxyManagedSettingsWarning: hasProxyManagedOnlyUserSettings(userSettings),
|
||||
isLoading: false,
|
||||
error: null,
|
||||
})
|
||||
@@ -647,6 +651,18 @@ export const useSettingsStore = create<SettingsStore>((set, get) => ({
|
||||
},
|
||||
}))
|
||||
|
||||
export function hasProxyManagedOnlyUserSettings(settings: UserSettings): boolean {
|
||||
const keys = Object.keys(settings)
|
||||
if (keys.length !== 1 || keys[0] !== 'env') return false
|
||||
|
||||
const env = settings.env
|
||||
if (typeof env !== 'object' || env === null || Array.isArray(env)) return false
|
||||
|
||||
const values = env as Record<string, unknown>
|
||||
return values.ANTHROPIC_API_KEY === 'PROXY_MANAGED'
|
||||
|| values.ANTHROPIC_AUTH_TOKEN === 'PROXY_MANAGED'
|
||||
}
|
||||
|
||||
subscribeLocaleChanges((locale) => {
|
||||
useSettingsStore.setState({ locale })
|
||||
applyDocumentLocale(locale)
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { hasProxyManagedOnlyUserSettings } from './settingsStore'
|
||||
|
||||
describe('proxy-managed user settings warning', () => {
|
||||
it('recognizes a proxy-only takeover placeholder', () => {
|
||||
expect(hasProxyManagedOnlyUserSettings({
|
||||
env: {
|
||||
ANTHROPIC_BASE_URL: 'http://127.0.0.1:15721',
|
||||
ANTHROPIC_API_KEY: 'PROXY_MANAGED',
|
||||
},
|
||||
})).toBe(true)
|
||||
})
|
||||
|
||||
it('does not flag a normal local model endpoint', () => {
|
||||
expect(hasProxyManagedOnlyUserSettings({
|
||||
env: {
|
||||
ANTHROPIC_BASE_URL: 'http://127.0.0.1:11434',
|
||||
ANTHROPIC_API_KEY: 'local-model-key',
|
||||
},
|
||||
})).toBe(false)
|
||||
})
|
||||
|
||||
it('does not flag a proxy placeholder when other user settings remain', () => {
|
||||
expect(hasProxyManagedOnlyUserSettings({
|
||||
env: {
|
||||
ANTHROPIC_BASE_URL: 'http://127.0.0.1:15721',
|
||||
ANTHROPIC_AUTH_TOKEN: 'PROXY_MANAGED',
|
||||
},
|
||||
language: 'Chinese',
|
||||
})).toBe(false)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user