From 2be8787fb532d2d9110cdb71ba944695a76d7d59 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Mon, 1 Jun 2026 15:51:55 -0600 Subject: [PATCH 1/3] Fix stale Codex auth state in desktop --- .../src/credentials/codex-auth.ts | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/agents-desktop/src/credentials/codex-auth.ts b/packages/agents-desktop/src/credentials/codex-auth.ts index cb739aebee..233bb11460 100644 --- a/packages/agents-desktop/src/credentials/codex-auth.ts +++ b/packages/agents-desktop/src/credentials/codex-auth.ts @@ -283,19 +283,44 @@ async function refreshCodexAuthIfNeeded( return next } +async function clearCodexAuth( + deps: Pick< + CodexAuthDeps, + `settings` | `getSecretStore` | `saveSettings` | `markCredentialsDirty` + > +): Promise { + deps.settings.codex = { enabled: false, source: null } + await deps.getSecretStore().delete(CODEX_AUTH_REF) + await deps.saveSettings() + deps.markCredentialsDirty() +} + export async function syncCodexEnvironment( - deps: Pick + deps: Pick< + CodexAuthDeps, + `settings` | `getSecretStore` | `saveSettings` | `markCredentialsDirty` + > ): Promise { process.env.ELECTRIC_CODEX_REQUIRE_OPT_IN = `1` delete process.env.ELECTRIC_CODEX_ACCESS_TOKEN const codex = deps.settings.codex ?? { enabled: false, source: null } if (!codex.enabled || !codex.source) return + const stored = await loadStoredCodexAuth(deps) - if (!stored) return - const refreshed = await refreshCodexAuthIfNeeded(deps, stored) + const refreshed = + stored?.source === codex.source + ? await refreshCodexAuthIfNeeded(deps, stored) + : null if (refreshed?.access) { process.env.ELECTRIC_CODEX_ACCESS_TOKEN = refreshed.access + return } + + // Avoid showing a false "Enabled" state when no usable access token can be + // produced. Desktop OAuth tokens should refresh through the OAuth token + // endpoint above; stale tokens imported from CLI/opencode auth files should be + // deleted rather than repeatedly trusted as an enabled desktop credential. + await clearCodexAuth(deps) } async function detectCodexSources( From cc5745b889f5ca7a167e4179df803f459269267c Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Mon, 1 Jun 2026 15:55:06 -0600 Subject: [PATCH 2/3] Add changeset for Codex auth fix --- .changeset/fix-codex-stale-auth.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fix-codex-stale-auth.md diff --git a/.changeset/fix-codex-stale-auth.md b/.changeset/fix-codex-stale-auth.md new file mode 100644 index 0000000000..60ca1ab9dc --- /dev/null +++ b/.changeset/fix-codex-stale-auth.md @@ -0,0 +1,5 @@ +--- +'@electric-ax/agents-desktop': patch +--- + +Clear stale Codex auth in the desktop app when no usable access token can be produced, preventing the UI from showing Codex as enabled while runs cannot authenticate. From a533c38b920dab6a329ec976dfa37f9417824932 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Tue, 2 Jun 2026 09:36:54 -0600 Subject: [PATCH 3/3] Address Codex auth review feedback --- .../agents-desktop/src/credentials/codex-auth.ts | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/packages/agents-desktop/src/credentials/codex-auth.ts b/packages/agents-desktop/src/credentials/codex-auth.ts index 233bb11460..7e9fa53d08 100644 --- a/packages/agents-desktop/src/credentials/codex-auth.ts +++ b/packages/agents-desktop/src/credentials/codex-auth.ts @@ -283,24 +283,14 @@ async function refreshCodexAuthIfNeeded( return next } -async function clearCodexAuth( - deps: Pick< - CodexAuthDeps, - `settings` | `getSecretStore` | `saveSettings` | `markCredentialsDirty` - > -): Promise { +async function clearCodexAuth(deps: CodexAuthDeps): Promise { deps.settings.codex = { enabled: false, source: null } await deps.getSecretStore().delete(CODEX_AUTH_REF) await deps.saveSettings() deps.markCredentialsDirty() } -export async function syncCodexEnvironment( - deps: Pick< - CodexAuthDeps, - `settings` | `getSecretStore` | `saveSettings` | `markCredentialsDirty` - > -): Promise { +export async function syncCodexEnvironment(deps: CodexAuthDeps): Promise { process.env.ELECTRIC_CODEX_REQUIRE_OPT_IN = `1` delete process.env.ELECTRIC_CODEX_ACCESS_TOKEN const codex = deps.settings.codex ?? { enabled: false, source: null }