Skip to content

Commit e5432ec

Browse files
committed
fix: sync codex cli auth into default profile
1 parent 268e24e commit e5432ec

File tree

4 files changed

+21
-6
lines changed

4 files changed

+21
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ Docs: https://docs.openclaw.ai
100100
- Gateway/websocket pairing bypass for disabled auth: skip device-pairing enforcement when `gateway.auth.mode=none` so Control UI connections behind reverse proxies no longer get stuck on `pairing required` (code 1008) despite auth being explicitly disabled. (#42931)
101101
- Auth/login lockout recovery: clear stale `auth_permanent` and `billing` disabled state for all profiles matching the target provider when `openclaw models auth login` is invoked, so users locked out by expired or revoked OAuth tokens can recover by re-authenticating instead of waiting for the cooldown timer to expire. (#43057)
102102
- Auto-reply/context-engine compaction: persist the exact embedded-run metadata compaction count for main and followup runner session accounting, so metadata-only auto-compactions no longer undercount multi-compaction runs. (#42629) thanks @uf-hy.
103+
- Auth/Codex CLI reuse: sync reused Codex CLI credentials into the supported `openai-codex:default` OAuth profile instead of reviving the deprecated `openai-codex:codex-cli` slot, so doctor cleanup no longer loops. (#45353) thanks @Gugu-sugar.
103104

104105
## 2026.3.12
105106

src/agents/auth-profiles.external-cli-sync.test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ vi.mock("./cli-credentials.js", () => ({
1616
const { syncExternalCliCredentials } = await import("./auth-profiles/external-cli-sync.js");
1717
const { CODEX_CLI_PROFILE_ID } = await import("./auth-profiles/constants.js");
1818

19+
const OPENAI_CODEX_DEFAULT_PROFILE_ID = "openai-codex:default";
20+
1921
describe("syncExternalCliCredentials", () => {
20-
it("syncs Codex CLI credentials into the compatibility auth profile", () => {
22+
it("syncs Codex CLI credentials into the supported default auth profile", () => {
2123
const expires = Date.now() + 60_000;
2224
mocks.readCodexCliCredentialsCached.mockReturnValue({
2325
type: "oauth",
@@ -39,13 +41,14 @@ describe("syncExternalCliCredentials", () => {
3941
expect(mocks.readCodexCliCredentialsCached).toHaveBeenCalledWith(
4042
expect.objectContaining({ ttlMs: expect.any(Number) }),
4143
);
42-
expect(store.profiles[CODEX_CLI_PROFILE_ID]).toMatchObject({
44+
expect(store.profiles[OPENAI_CODEX_DEFAULT_PROFILE_ID]).toMatchObject({
4345
type: "oauth",
4446
provider: "openai-codex",
4547
access: "access-token",
4648
refresh: "refresh-token",
4749
expires,
4850
accountId: "acct_123",
4951
});
52+
expect(store.profiles[CODEX_CLI_PROFILE_ID]).toBeUndefined();
5053
});
5154
});

src/agents/auth-profiles/external-cli-sync.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
readMiniMaxCliCredentialsCached,
55
} from "../cli-credentials.js";
66
import {
7-
CODEX_CLI_PROFILE_ID,
87
EXTERNAL_CLI_NEAR_EXPIRY_MS,
98
EXTERNAL_CLI_SYNC_TTL_MS,
109
QWEN_CLI_PROFILE_ID,
@@ -13,6 +12,8 @@ import {
1312
} from "./constants.js";
1413
import type { AuthProfileCredential, AuthProfileStore, OAuthCredential } from "./types.js";
1514

15+
const OPENAI_CODEX_DEFAULT_PROFILE_ID = "openai-codex:default";
16+
1617
function shallowEqualOAuthCredentials(a: OAuthCredential | undefined, b: OAuthCredential): boolean {
1718
if (!a) {
1819
return false;
@@ -140,7 +141,7 @@ export function syncExternalCliCredentials(store: AuthProfileStore): boolean {
140141
if (
141142
syncExternalCliCredentialsForProvider(
142143
store,
143-
CODEX_CLI_PROFILE_ID,
144+
OPENAI_CODEX_DEFAULT_PROFILE_ID,
144145
"openai-codex",
145146
() => readCodexCliCredentialsCached({ ttlMs: EXTERNAL_CLI_SYNC_TTL_MS }),
146147
now,

src/commands/doctor-auth.deprecated-cli-profiles.test.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ describe("maybeRemoveDeprecatedCliAuthProfiles", () => {
6363
refresh: "token-r2",
6464
expires: Date.now() + 60_000,
6565
},
66+
"openai-codex:default": {
67+
type: "oauth",
68+
provider: "openai-codex",
69+
access: "token-c",
70+
refresh: "token-r3",
71+
expires: Date.now() + 60_000,
72+
},
6673
},
6774
},
6875
null,
@@ -76,10 +83,11 @@ describe("maybeRemoveDeprecatedCliAuthProfiles", () => {
7683
profiles: {
7784
"anthropic:claude-cli": { provider: "anthropic", mode: "oauth" },
7885
"openai-codex:codex-cli": { provider: "openai-codex", mode: "oauth" },
86+
"openai-codex:default": { provider: "openai-codex", mode: "oauth" },
7987
},
8088
order: {
8189
anthropic: ["anthropic:claude-cli"],
82-
"openai-codex": ["openai-codex:codex-cli"],
90+
"openai-codex": ["openai-codex:codex-cli", "openai-codex:default"],
8391
},
8492
},
8593
} as const;
@@ -94,10 +102,12 @@ describe("maybeRemoveDeprecatedCliAuthProfiles", () => {
94102
};
95103
expect(raw.profiles?.["anthropic:claude-cli"]).toBeUndefined();
96104
expect(raw.profiles?.["openai-codex:codex-cli"]).toBeUndefined();
105+
expect(raw.profiles?.["openai-codex:default"]).toBeDefined();
97106

98107
expect(next.auth?.profiles?.["anthropic:claude-cli"]).toBeUndefined();
99108
expect(next.auth?.profiles?.["openai-codex:codex-cli"]).toBeUndefined();
109+
expect(next.auth?.profiles?.["openai-codex:default"]).toBeDefined();
100110
expect(next.auth?.order?.anthropic).toBeUndefined();
101-
expect(next.auth?.order?.["openai-codex"]).toBeUndefined();
111+
expect(next.auth?.order?.["openai-codex"]).toEqual(["openai-codex:default"]);
102112
});
103113
});

0 commit comments

Comments
 (0)