From 2db2dcb4390cba2980298a0c67dd01d89fc3eeca Mon Sep 17 00:00:00 2001 From: Mega Mind <146339422+M3gA-Mind@users.noreply.github.com> Date: Sat, 18 Jul 2026 09:12:21 +0530 Subject: [PATCH] fix(i18n): localize the Codex auth button (Closes #4852) (#4992) --- .../components/settings/panels/AIPanel.tsx | 2 +- .../panels/__tests__/AIPanel.test.tsx | 24 +++++++++++++++++-- app/src/lib/i18n/ar.ts | 2 ++ app/src/lib/i18n/bn.ts | 2 ++ app/src/lib/i18n/de.ts | 3 +++ app/src/lib/i18n/en.ts | 2 ++ app/src/lib/i18n/es.ts | 3 +++ app/src/lib/i18n/fr.ts | 3 +++ app/src/lib/i18n/hi.ts | 2 ++ app/src/lib/i18n/id.ts | 2 ++ app/src/lib/i18n/it.ts | 2 ++ app/src/lib/i18n/ko.ts | 2 ++ app/src/lib/i18n/pl.ts | 2 ++ app/src/lib/i18n/pt.ts | 2 ++ app/src/lib/i18n/ru.ts | 2 ++ app/src/lib/i18n/zh-CN.ts | 2 ++ 16 files changed, 54 insertions(+), 3 deletions(-) diff --git a/app/src/components/settings/panels/AIPanel.tsx b/app/src/components/settings/panels/AIPanel.tsx index f8579206a..4985206cf 100644 --- a/app/src/components/settings/panels/AIPanel.tsx +++ b/app/src/components/settings/panels/AIPanel.tsx @@ -3319,7 +3319,7 @@ const AIPanel = ({ embedded = false }: AIPanelProps = {}) => { disabled={busyAction === 'codex-auth' || busyAction === 'toggle-openai'}> {busyAction === 'codex-auth' || busyAction === 'toggle-openai' ? t('settings.ai.connecting') - : t('settings.ai.codexAuthButton', 'Codex 인증')} + : t('settings.ai.codexAuthButton', 'Connect Codex')} {t( diff --git a/app/src/components/settings/panels/__tests__/AIPanel.test.tsx b/app/src/components/settings/panels/__tests__/AIPanel.test.tsx index 2d319f2cb..2daa48468 100644 --- a/app/src/components/settings/panels/__tests__/AIPanel.test.tsx +++ b/app/src/components/settings/panels/__tests__/AIPanel.test.tsx @@ -893,6 +893,26 @@ describe('AIPanel', () => { expect(screen.queryByRole('switch', { name: /Disconnect OpenAI/i })).not.toBeInTheDocument(); }); + // Regression for #4852: the Codex auth button had a hardcoded Korean fallback + // (`Codex 인증`) because the `settings.ai.codexAuthButton` key was missing from + // every locale, so the English UI rendered Korean text. Assert the English + // label renders and no Korean survives. + it('renders the Codex auth button with the active-locale (English) label', async () => { + vi.mocked(loadAISettings).mockResolvedValue({ ...baseSettings, cloudProviders: [] }); + + renderWithProviders(); + + await waitFor(() => + expect(screen.getByRole('switch', { name: /Connect OpenAI/i })).toBeInTheDocument() + ); + + const codexButton = screen.getByRole('button', { name: /Connect Codex/i }); + expect(codexButton).toBeInTheDocument(); + // The Korean fallback must be gone from the English onboarding screen. + expect(screen.queryByText(/인증/)).not.toBeInTheDocument(); + expect(screen.queryByRole('button', { name: /Codex 인증/i })).not.toBeInTheDocument(); + }); + it('connects OpenAI through Codex CLI auth without storing an API key', async () => { vi.mocked(loadAISettings).mockResolvedValue({ ...baseSettings, cloudProviders: [] }); @@ -902,7 +922,7 @@ describe('AIPanel', () => { expect(screen.getByRole('switch', { name: /Connect OpenAI/i })).toBeInTheDocument() ); - fireEvent.click(screen.getByRole('button', { name: /Codex 인증/i })); + fireEvent.click(screen.getByRole('button', { name: /Connect Codex/i })); await waitFor(() => expect(vi.mocked(importOpenAiCodexCliAuth)).toHaveBeenCalledTimes(1)); expect(vi.mocked(startOpenAiCodexOAuth)).not.toHaveBeenCalled(); @@ -947,7 +967,7 @@ describe('AIPanel', () => { expect(screen.getByRole('switch', { name: /Connect OpenAI/i })).toBeInTheDocument() ); - fireEvent.click(screen.getByRole('button', { name: /Codex 인증/i })); + fireEvent.click(screen.getByRole('button', { name: /Connect Codex/i })); await waitFor(() => expect(screen.getByRole('alert')).toHaveTextContent(expectedMessage)); expect(vi.mocked(setCloudProviderKey)).not.toHaveBeenCalled(); diff --git a/app/src/lib/i18n/ar.ts b/app/src/lib/i18n/ar.ts index 0a3dd433c..57832ea70 100644 --- a/app/src/lib/i18n/ar.ts +++ b/app/src/lib/i18n/ar.ts @@ -4523,6 +4523,8 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': 'وقع مع OpenRouter وإستيراد مفتاح ×xxxxx متحكم به مستخدماً', 'settings.ai.connecting': 'جارٍ الاتصال...', + 'settings.ai.codexAuthButton': 'ربط Codex', + 'settings.ai.codexAuthHelper': 'يستخدم تسجيل دخول Codex CLI الحالي من ~/.codex/auth.json.', 'settings.ai.backgroundLoops': 'حلقات الخلفية', 'settings.ai.backgroundLoopsDesc': 'شاهدْ ما يَعْملُ بدون رسالةِ دردشةِ، يَتوقّفُ عملَ نبضات القلب، ويَتفحصُ مؤخراً دفترِ دفاترِ الإئتمانِ.', diff --git a/app/src/lib/i18n/bn.ts b/app/src/lib/i18n/bn.ts index 3138bdb6c..491867a9c 100644 --- a/app/src/lib/i18n/bn.ts +++ b/app/src/lib/i18n/bn.ts @@ -4638,6 +4638,8 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': 'xqxqxx সহযোগে সাইন করুন এবং xqxyqx ব্যবহার করে একটি ব্যবহারকারী xxqx কী ইম্পোর্ট করুন', 'settings.ai.connecting': 'সংযোগ করা হচ্ছে...', + 'settings.ai.codexAuthButton': 'Codex সংযুক্ত করুন', + 'settings.ai.codexAuthHelper': '~/.codex/auth.json থেকে বিদ্যমান Codex CLI লগইন ব্যবহার করে।', 'settings.ai.backgroundLoops': 'ব্যাকগ্রাউন্ড লুপস', 'settings.ai.backgroundLoopsDesc': 'লক্ষ্য করুন যে, কোন আড্ডা ছাড়াই কি করা হয়, হার্টবিটের কাজ বিরতি দিন এবং সম্প্রতি ক্রেডিট কার্ড পরীক্ষা করুন ।', diff --git a/app/src/lib/i18n/de.ts b/app/src/lib/i18n/de.ts index 26e34222d..dee022958 100644 --- a/app/src/lib/i18n/de.ts +++ b/app/src/lib/i18n/de.ts @@ -4769,6 +4769,9 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': 'Melden Sie sich mit OpenRouter an und importieren Sie einen benutzergesteuerten API-Schlüssel mit PKCE.', 'settings.ai.connecting': 'Verbindung wird hergestellt...', + 'settings.ai.codexAuthButton': 'Codex verbinden', + 'settings.ai.codexAuthHelper': + 'Verwendet die vorhandene Codex-CLI-Anmeldung aus ~/.codex/auth.json.', 'settings.ai.backgroundLoops': 'Hintergrundschleifen', 'settings.ai.backgroundLoopsDesc': 'Sehen Sie, was ohne Chat-Nachricht läuft, pausieren Sie die Herzschlagarbeit und überprüfen Sie die letzten Kreditbuchzeilen.', diff --git a/app/src/lib/i18n/en.ts b/app/src/lib/i18n/en.ts index 70e22d526..7540db7f1 100644 --- a/app/src/lib/i18n/en.ts +++ b/app/src/lib/i18n/en.ts @@ -5344,6 +5344,8 @@ const en: TranslationMap = { 'settings.ai.openRouterOauthDescription': 'Sign in with OpenRouter and import a user-controlled API key using PKCE.', 'settings.ai.connecting': 'Connecting...', + 'settings.ai.codexAuthButton': 'Connect Codex', + 'settings.ai.codexAuthHelper': 'Uses the existing Codex CLI login from ~/.codex/auth.json.', 'settings.ai.backgroundLoops': 'Background loops', 'settings.ai.backgroundLoopsDesc': 'See what runs without a chat message, pause heartbeat work, and inspect recent credit ledger rows.', diff --git a/app/src/lib/i18n/es.ts b/app/src/lib/i18n/es.ts index 0c2cd3455..aa8eaef77 100644 --- a/app/src/lib/i18n/es.ts +++ b/app/src/lib/i18n/es.ts @@ -4717,6 +4717,9 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': 'Inicia sesión con OpenRouter e importa una clave API controlada por el usuario usando PKCE.', 'settings.ai.connecting': 'Conectando...', + 'settings.ai.codexAuthButton': 'Conectar Codex', + 'settings.ai.codexAuthHelper': + 'Usa el inicio de sesión existente de Codex CLI desde ~/.codex/auth.json.', 'settings.ai.backgroundLoops': 'Bucles de fondo', 'settings.ai.backgroundLoopsDesc': 'Vea qué se ejecuta sin un mensaje de chat, pause el trabajo de latido y examine las filas recientes del libro mayor de créditos.', diff --git a/app/src/lib/i18n/fr.ts b/app/src/lib/i18n/fr.ts index 18ca04b8d..14d7f4a90 100644 --- a/app/src/lib/i18n/fr.ts +++ b/app/src/lib/i18n/fr.ts @@ -4746,6 +4746,9 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': "Connectez-vous avec OpenRouter et importez une clé API contrôlée par l'utilisateur en utilisant PKCE.", 'settings.ai.connecting': 'Connexion...', + 'settings.ai.codexAuthButton': 'Connecter Codex', + 'settings.ai.codexAuthHelper': + 'Utilise la connexion Codex CLI existante depuis ~/.codex/auth.json.', 'settings.ai.backgroundLoops': 'Boucles de fond', 'settings.ai.backgroundLoopsDesc': "Voyez ce qui s'exécute sans message de discussion, interrompez le travail du battement de cœur et inspectez les lignes récentes du grand livre de crédit.", diff --git a/app/src/lib/i18n/hi.ts b/app/src/lib/i18n/hi.ts index 330e0c9bf..7fb5a9dd6 100644 --- a/app/src/lib/i18n/hi.ts +++ b/app/src/lib/i18n/hi.ts @@ -4637,6 +4637,8 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': 'OpenRouter के साथ साइन इन करें और PKCE का उपयोग करके उपयोगकर्ता नियंत्रित API कुंजी आयात करें।', 'settings.ai.connecting': 'कनेक्ट हो रहा है...', + 'settings.ai.codexAuthButton': 'Codex कनेक्ट करें', + 'settings.ai.codexAuthHelper': '~/.codex/auth.json से मौजूदा Codex CLI लॉगिन का उपयोग करता है।', 'settings.ai.backgroundLoops': 'पृष्ठभूमि लूप', 'settings.ai.backgroundLoopsDesc': 'क्या एक चैट संदेश के बिना चलाता है, दिल की धड़कन काम को रोकें, और हाल ही में क्रेडिट लेजर पंक्तियों का निरीक्षण करें।', diff --git a/app/src/lib/i18n/id.ts b/app/src/lib/i18n/id.ts index d5b348d7e..126d0e8c0 100644 --- a/app/src/lib/i18n/id.ts +++ b/app/src/lib/i18n/id.ts @@ -4653,6 +4653,8 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': 'Masuk dengan kunci OpenRouter dan impor sebuah user yang dikendalikan API menggunakan PKCE.', 'settings.ai.connecting': 'Menghubungkan...', + 'settings.ai.codexAuthButton': 'Hubungkan Codex', + 'settings.ai.codexAuthHelper': 'Menggunakan login Codex CLI yang ada dari ~/.codex/auth.json.', 'settings.ai.backgroundLoops': 'Perulangan latar belakang', 'settings.ai.backgroundLoopsDesc': 'Lihat apa yang berjalan tanpa pesan obrolan, jeda kerja detak jantung, dan memeriksa buku kas kredit baru-baru ini.', diff --git a/app/src/lib/i18n/it.ts b/app/src/lib/i18n/it.ts index 29f28efa2..676751c94 100644 --- a/app/src/lib/i18n/it.ts +++ b/app/src/lib/i18n/it.ts @@ -4711,6 +4711,8 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': "Accedi con OpenRouter e importa una chiave API controllata dall'utente usando PKCE.", 'settings.ai.connecting': 'Connessione in corso...', + 'settings.ai.codexAuthButton': 'Connetti Codex', + 'settings.ai.codexAuthHelper': 'Usa il login Codex CLI esistente da ~/.codex/auth.json.', 'settings.ai.backgroundLoops': 'Loop in background', 'settings.ai.backgroundLoopsDesc': 'Vedi cosa funziona senza un messaggio di chat, metti in pausa il lavoro del battito cardiaco e ispeziona le righe recenti del libro mastro dei crediti.', diff --git a/app/src/lib/i18n/ko.ts b/app/src/lib/i18n/ko.ts index 2d255d1c7..503625b04 100644 --- a/app/src/lib/i18n/ko.ts +++ b/app/src/lib/i18n/ko.ts @@ -4585,6 +4585,8 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': 'OpenRouter로 로그인하고 PKCE를 사용해 사용자가 제어하는 API 키를 가져옵니다.', 'settings.ai.connecting': '연결 중...', + 'settings.ai.codexAuthButton': 'Codex 연결', + 'settings.ai.codexAuthHelper': '~/.codex/auth.json의 기존 Codex CLI 로그인을 사용합니다.', 'settings.ai.backgroundLoops': '백그라운드 루프', 'settings.ai.backgroundLoopsDesc': '채팅 메시지 없이 실행되는 항목을 확인하고, 하트비트 작업을 일시 중지하며, 최근 크레딧 원장 행을 검사합니다.', diff --git a/app/src/lib/i18n/pl.ts b/app/src/lib/i18n/pl.ts index 025c3fe99..c89ad8d05 100644 --- a/app/src/lib/i18n/pl.ts +++ b/app/src/lib/i18n/pl.ts @@ -4707,6 +4707,8 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': 'Zaloguj się przez OpenRouter i zaimportuj kontrolowany przez użytkownika klucz API z użyciem PKCE.', 'settings.ai.connecting': 'Łączenie...', + 'settings.ai.codexAuthButton': 'Połącz Codex', + 'settings.ai.codexAuthHelper': 'Używa istniejącego logowania Codex CLI z ~/.codex/auth.json.', 'settings.ai.backgroundLoops': 'Pętle w tle', 'settings.ai.backgroundLoopsDesc': 'Zobacz, co działa bez wiadomości na czacie, wstrzymaj pracę heartbeat i sprawdź ostatnie wiersze księgi kredytów.', diff --git a/app/src/lib/i18n/pt.ts b/app/src/lib/i18n/pt.ts index 84bc12ba9..845114238 100644 --- a/app/src/lib/i18n/pt.ts +++ b/app/src/lib/i18n/pt.ts @@ -4704,6 +4704,8 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': 'Faça login com OpenRouter e importe uma chave API controlada pelo usuário usando PKCE.', 'settings.ai.connecting': 'Conectando...', + 'settings.ai.codexAuthButton': 'Conectar Codex', + 'settings.ai.codexAuthHelper': 'Usa o login existente da CLI do Codex de ~/.codex/auth.json.', 'settings.ai.backgroundLoops': 'Loops de segundo plano.', 'settings.ai.backgroundLoopsDesc': 'Veja o que funciona sem uma mensagem de chat, pause o trabalho do pulso e inspecione as linhas recentes do livro razão de créditos.', diff --git a/app/src/lib/i18n/ru.ts b/app/src/lib/i18n/ru.ts index 667528bde..2e8256102 100644 --- a/app/src/lib/i18n/ru.ts +++ b/app/src/lib/i18n/ru.ts @@ -4681,6 +4681,8 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': 'Войдите в систему с помощью OpenRouter и импортируйте управляемый пользователем ключ API с помощью PKCE.', 'settings.ai.connecting': 'Подключение...', + 'settings.ai.codexAuthButton': 'Подключить Codex', + 'settings.ai.codexAuthHelper': 'Использует существующий вход Codex CLI из ~/.codex/auth.json.', 'settings.ai.backgroundLoops': 'Фоновые циклы', 'settings.ai.backgroundLoopsDesc': 'Посмотрите, что выполняется без сообщения чата, приостановите работу Heartbeat и проверьте последние строки кредитной книги.', diff --git a/app/src/lib/i18n/zh-CN.ts b/app/src/lib/i18n/zh-CN.ts index 99df09b5d..678738cee 100644 --- a/app/src/lib/i18n/zh-CN.ts +++ b/app/src/lib/i18n/zh-CN.ts @@ -4387,6 +4387,8 @@ const messages: TranslationMap = { 'settings.ai.openRouterOauthDescription': '使用 OpenRouter 登录,并通过 PKCE 导入由用户控制的 API 密钥。', 'settings.ai.connecting': '正在连接...', + 'settings.ai.codexAuthButton': '连接 Codex', + 'settings.ai.codexAuthHelper': '使用来自 ~/.codex/auth.json 的现有 Codex CLI 登录。', 'settings.ai.backgroundLoops': '背景循环', 'settings.ai.backgroundLoopsDesc': '查看没有聊天消息时运行的内容,暂停心跳任务,并检查最近的额度账本行。',