From 803b92a112ec13a44e7741aa8f2d8dc880fac5ed Mon Sep 17 00:00:00 2001 From: blazz Date: Wed, 5 Aug 2026 08:34:39 -0400 Subject: [PATCH] feat(codex): add frontend bridge types and i18n keys Expose ADR 0003 account commands to React via the typed invoke bridge, add bridge DTOs (CodexAccount, snapshots, switch result, state), and add the CodexAccounts locale keys for en-US and es-MX. --- apps/desktop-tauri/src/i18n/keys.ts | 13 ++++++ apps/desktop-tauri/src/lib/tauri.ts | 52 ++++++++++++++++++++++++ apps/desktop-tauri/src/types/bridge.ts | 55 ++++++++++++++++++++++++++ rust/src/locale.rs | 13 ++++++ rust/src/locale/en-US.ftl | 13 ++++++ rust/src/locale/es-MX.ftl | 13 ++++++ 6 files changed, 159 insertions(+) diff --git a/apps/desktop-tauri/src/i18n/keys.ts b/apps/desktop-tauri/src/i18n/keys.ts index 28811f426f..72c6057d57 100644 --- a/apps/desktop-tauri/src/i18n/keys.ts +++ b/apps/desktop-tauri/src/i18n/keys.ts @@ -293,6 +293,19 @@ export const ALL_LOCALE_KEYS = [ "ProviderClaudeDailyRoutinesUsageHelp", "ProviderCodexSparkUsage", "ProviderCodexSparkUsageHelp", + "CodexAccountsTitle", + "CodexAccountsHint", + "CodexAccountsAddButton", + "CodexAccountsSwitchButton", + "CodexAccountsFetchButton", + "CodexAccountsRemoveButton", + "CodexAccountsEmpty", + "CodexAccountsSourceAmbient", + "CodexAccountsSourceManaged", + "CodexAccountsUsageUnavailable", + "CodexSwitchSuccess", + "CodexSwitchRestartPrompt", + "CodexAccountsRestartDesktop", "ProviderCursorCookieSourceHelp", "ProviderCursorCreditsHelp", "AutoFallbackHelp", diff --git a/apps/desktop-tauri/src/lib/tauri.ts b/apps/desktop-tauri/src/lib/tauri.ts index 27051c75e5..b51844fb58 100644 --- a/apps/desktop-tauri/src/lib/tauri.ts +++ b/apps/desktop-tauri/src/lib/tauri.ts @@ -34,6 +34,10 @@ import type { TrayVisibilityStatusDto, UsageSpendSummary, CodexLocalProjectUsageSnapshot, + CodexAccount, + CodexAccountUsageSnapshot, + CodexAccountsStateBridge, + CodexSwitchResult, } from "../types/bridge"; export function getBootstrapState(): Promise { @@ -436,3 +440,51 @@ export function flyoutStoredSize(): Promise<[number, number] | null> { export function quitApp(): Promise { return invoke("quit_app"); } + +// ── Codex multi-account (ADR 0003) ─────────────────────────────────── + +export function codexAccountsList(): Promise { + return invoke("codex_accounts_list"); +} + +export function codexAccountAdd(): Promise { + return invoke("codex_account_add"); +} + +export function codexAccountRemove(id: string): Promise { + return invoke("codex_account_remove", { id }); +} + +export function codexAccountSwitch(id: string): Promise { + return invoke("codex_account_switch", { id }); +} + +export function codexAccountFetch( + id: string, +): Promise { + return invoke("codex_account_fetch", { id }); +} + +export function codexAccountSnapshots(): Promise< + Record +> { + return invoke>( + "codex_account_snapshots", + ); +} + +export function codexAccountRestartDesktop( + sessionRoot?: string | null, + backupDestination?: string | null, + restoreSource?: string | null, +): Promise { + return invoke("codex_account_restart_desktop", { + sessionRoot, + backupDestination, + restoreSource, + }); +} + +export function getCodexAccountsState(): Promise { + return invoke("get_codex_accounts_state"); +} diff --git a/apps/desktop-tauri/src/types/bridge.ts b/apps/desktop-tauri/src/types/bridge.ts index 89e16af7a4..3d91b68cae 100644 --- a/apps/desktop-tauri/src/types/bridge.ts +++ b/apps/desktop-tauri/src/types/bridge.ts @@ -738,3 +738,58 @@ export interface RegionOption { value: string; label: string; } + +// ── Codex multi-account (ADR 0003) ─────────────────────────────────── + +export type CodexAccountSource = "ambient" | "managedByApp"; + +export interface CodexAccount { + id: string; + nickname: string | null; + emailHint: string | null; + authSubject: string | null; + providerAccountId: string | null; + codexHomePath: string; + source: CodexAccountSource; + createdAt: string; + updatedAt: string; + lastAuthenticatedAt: string | null; +} + +export interface CodexUsageWindow { + usedPercent: number; + resetAt: string | null; + limitWindowSeconds: number; +} + +export interface CodexCreditsBalance { + hasCredits: boolean; + unlimited: boolean; + balance: number | null; +} + +export interface CodexAccountUsageSnapshot { + email: string | null; + providerAccountId: string | null; + plan: string | null; + allowed: boolean | null; + limitReached: boolean | null; + primaryWindow: CodexUsageWindow | null; + secondaryWindow: CodexUsageWindow | null; + credits: CodexCreditsBalance | null; + updatedAt: string; +} + +export interface CodexSwitchResult { + materializedAccount: CodexAccount | null; + backupPath: string | null; + ambientAccount: CodexAccount | null; + desktopSessionBackupPath: string | null; + desktopSessionRestorePath: string | null; + desktopSessionRestoreExists: boolean; +} + +export interface CodexAccountsStateBridge { + accounts: CodexAccount[]; + snapshots: Record; +} diff --git a/rust/src/locale.rs b/rust/src/locale.rs index 7bb2b92a07..cf86892e56 100644 --- a/rust/src/locale.rs +++ b/rust/src/locale.rs @@ -509,6 +509,19 @@ locale_keys! { ProviderClaudeDailyRoutinesUsageHelp, ProviderCodexSparkUsage, ProviderCodexSparkUsageHelp, + CodexAccountsTitle, + CodexAccountsHint, + CodexAccountsAddButton, + CodexAccountsSwitchButton, + CodexAccountsFetchButton, + CodexAccountsRemoveButton, + CodexAccountsEmpty, + CodexAccountsSourceAmbient, + CodexAccountsSourceManaged, + CodexAccountsUsageUnavailable, + CodexSwitchSuccess, + CodexSwitchRestartPrompt, + CodexAccountsRestartDesktop, ProviderCursorCookieSourceHelp, ProviderCursorCreditsHelp, AutoFallbackHelp, diff --git a/rust/src/locale/en-US.ftl b/rust/src/locale/en-US.ftl index aa289501e0..42946a7dee 100644 --- a/rust/src/locale/en-US.ftl +++ b/rust/src/locale/en-US.ftl @@ -288,6 +288,19 @@ ProviderClaudeDailyRoutinesUsage = Show Daily Routines usage ProviderClaudeDailyRoutinesUsageHelp = Show the Daily Routines quota row for Claude web and OAuth usage. ProviderCodexSparkUsage = Show Codex Spark usage ProviderCodexSparkUsageHelp = Show Codex Spark quota rows without hiding credits or other extra usage. +CodexAccountsTitle = Codex Accounts +CodexAccountsHint = Manage multiple Codex accounts. Each account lives in its own managed home; switching updates the active identity. +CodexAccountsAddButton = Add account +CodexAccountsSwitchButton = Switch +CodexAccountsFetchButton = Refresh usage +CodexAccountsRemoveButton = Remove +CodexAccountsEmpty = No Codex accounts found. +CodexAccountsSourceAmbient = Ambient +CodexAccountsSourceManaged = Managed +CodexAccountsUsageUnavailable = No usage data +CodexSwitchSuccess = Active account switched. +CodexSwitchRestartPrompt = Restart Codex Desktop to load the restored session? +CodexAccountsRestartDesktop = Restart Codex Desktop ProviderCursorCookieSourceHelp = Automatic imports browser cookies or stored sessions. ProviderCursorCreditsHelp = On-demand usage beyond included plan limits. AutoFallbackHelp = Auto falls back to the next source if the preferred one fails. diff --git a/rust/src/locale/es-MX.ftl b/rust/src/locale/es-MX.ftl index 044c7a9bb6..f52199c132 100644 --- a/rust/src/locale/es-MX.ftl +++ b/rust/src/locale/es-MX.ftl @@ -282,6 +282,19 @@ ProviderClaudeDailyRoutinesUsage = Mostrar uso de Daily Routines ProviderClaudeDailyRoutinesUsageHelp = Muestra la fila de cuota Daily Routines en el uso web/OAuth de Claude. ProviderCodexSparkUsage = Show Codex Spark usage ProviderCodexSparkUsageHelp = Show Codex Spark quota rows without hiding credits or other extra usage. +CodexAccountsTitle = Cuentas de Codex +CodexAccountsHint = Administra varias cuentas de Codex. Cada cuenta vive en su propio hogar administrado; al cambiar se actualiza la identidad activa. +CodexAccountsAddButton = Añadir cuenta +CodexAccountsSwitchButton = Cambiar +CodexAccountsFetchButton = Actualizar uso +CodexAccountsRemoveButton = Quitar +CodexAccountsEmpty = No se encontraron cuentas de Codex. +CodexAccountsSourceAmbient = Ambiental +CodexAccountsSourceManaged = Administrada +CodexAccountsUsageUnavailable = Sin datos de uso +CodexSwitchSuccess = Cuenta activa cambiada. +CodexSwitchRestartPrompt = ¿Reiniciar Codex Desktop para cargar la sesión restaurada? +CodexAccountsRestartDesktop = Reiniciar Codex Desktop ProviderCursorCookieSourceHelp = Importa automáticamente cookies del navegador o sesiones almacenadas. ProviderCursorCreditsHelp = Uso bajo demanda más allá de los límites del plan incluido. AutoFallbackHelp = Auto recurre a la siguiente fuente si la preferida falla.