claude-code-openai 0.1.12 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +93 -30
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -186131,6 +186131,32 @@ async function getOpenAIAccessToken() {
186131
186131
  }
186132
186132
  return tokens.access_token;
186133
186133
  }
186134
+ async function obtainApiKey(idToken) {
186135
+ const controller = new AbortController;
186136
+ const timer = setTimeout(() => controller.abort(), 15000);
186137
+ try {
186138
+ const body = new URLSearchParams({
186139
+ grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
186140
+ client_id: OPENAI_OAUTH_CONFIG.CLIENT_ID,
186141
+ requested_token: "openai-api-key",
186142
+ subject_token: idToken,
186143
+ subject_token_type: "urn:ietf:params:oauth:token-type:id_token"
186144
+ });
186145
+ const resp = await fetch(OPENAI_OAUTH_CONFIG.TOKEN_URL, {
186146
+ method: "POST",
186147
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
186148
+ body: body.toString(),
186149
+ signal: controller.signal
186150
+ });
186151
+ if (!resp.ok) {
186152
+ throw new Error(`API key exchange failed: ${resp.status}`);
186153
+ }
186154
+ const data = await resp.json();
186155
+ return data.access_token;
186156
+ } finally {
186157
+ clearTimeout(timer);
186158
+ }
186159
+ }
186134
186160
  async function startOpenAIOAuthFlow(options) {
186135
186161
  const codeVerifier = generateCodeVerifier();
186136
186162
  const codeChallenge = generateCodeChallenge(codeVerifier);
@@ -186139,14 +186165,15 @@ async function startOpenAIOAuthFlow(options) {
186139
186165
  const port = await listener.start(OPENAI_OAUTH_CONFIG.CALLBACK_PORT);
186140
186166
  const redirectUri = `http://localhost:${port}/auth/callback`;
186141
186167
  const authUrl = new URL(OPENAI_OAUTH_CONFIG.AUTHORIZE_URL);
186142
- authUrl.searchParams.append("client_id", OPENAI_OAUTH_CONFIG.CLIENT_ID);
186143
186168
  authUrl.searchParams.append("response_type", "code");
186169
+ authUrl.searchParams.append("client_id", OPENAI_OAUTH_CONFIG.CLIENT_ID);
186144
186170
  authUrl.searchParams.append("redirect_uri", redirectUri);
186145
186171
  authUrl.searchParams.append("scope", OPENAI_OAUTH_CONFIG.SCOPES.join(" "));
186146
186172
  authUrl.searchParams.append("code_challenge", codeChallenge);
186147
186173
  authUrl.searchParams.append("code_challenge_method", "S256");
186174
+ authUrl.searchParams.append("id_token_add_organizations", "true");
186175
+ authUrl.searchParams.append("codex_cli_simplified_flow", "true");
186148
186176
  authUrl.searchParams.append("state", state3);
186149
- authUrl.searchParams.append("audience", OPENAI_OAUTH_CONFIG.AUDIENCE);
186150
186177
  const urlStr = authUrl.toString();
186151
186178
  logForDebugging(`[OpenAI OAuth] Authorization URL: ${urlStr}`);
186152
186179
  if (options?.onUrl) {
@@ -186175,27 +186202,39 @@ async function startOpenAIOAuthFlow(options) {
186175
186202
  const tokenTimer = setTimeout(() => tokenController.abort(), 15000);
186176
186203
  let tokenResponse;
186177
186204
  try {
186205
+ const tokenBody = new URLSearchParams({
186206
+ grant_type: "authorization_code",
186207
+ code: authorizationCode,
186208
+ redirect_uri: redirectUri,
186209
+ client_id: OPENAI_OAUTH_CONFIG.CLIENT_ID,
186210
+ code_verifier: codeVerifier
186211
+ });
186178
186212
  tokenResponse = await fetch(OPENAI_OAUTH_CONFIG.TOKEN_URL, {
186179
186213
  method: "POST",
186180
- headers: { "Content-Type": "application/json" },
186181
- body: JSON.stringify({
186182
- grant_type: "authorization_code",
186183
- code: authorizationCode,
186184
- redirect_uri: redirectUri,
186185
- client_id: OPENAI_OAUTH_CONFIG.CLIENT_ID,
186186
- code_verifier: codeVerifier
186187
- }),
186214
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
186215
+ body: tokenBody.toString(),
186188
186216
  signal: tokenController.signal
186189
186217
  });
186190
186218
  } finally {
186191
186219
  clearTimeout(tokenTimer);
186192
186220
  }
186193
186221
  if (!tokenResponse.ok) {
186194
- throw new Error(`Token exchange failed: ${tokenResponse.status} ${tokenResponse.statusText}`);
186222
+ const errBody = await tokenResponse.text().catch(() => "");
186223
+ throw new Error(`Token exchange failed: ${tokenResponse.status} ${tokenResponse.statusText} ${errBody}`);
186195
186224
  }
186196
186225
  const data = await tokenResponse.json();
186226
+ logForDebugging("[OpenAI OAuth] Token exchange succeeded, obtaining API key...");
186227
+ let apiKey = null;
186228
+ if (data.id_token) {
186229
+ try {
186230
+ apiKey = await obtainApiKey(data.id_token);
186231
+ logForDebugging("[OpenAI OAuth] API key obtained successfully");
186232
+ } catch (err) {
186233
+ logForDebugging(`[OpenAI OAuth] API key exchange failed (will use access_token): ${err instanceof Error ? err.message : String(err)}`);
186234
+ }
186235
+ }
186197
186236
  const tokens = {
186198
- access_token: data.access_token,
186237
+ access_token: apiKey || data.access_token,
186199
186238
  refresh_token: data.refresh_token || null,
186200
186239
  expires_at: data.expires_in ? Date.now() + data.expires_in * 1000 : null,
186201
186240
  id_token: data.id_token
@@ -186215,10 +186254,10 @@ var init_openai_oauth = __esm(() => {
186215
186254
  init_auth_code_listener();
186216
186255
  OPENAI_OAUTH_CONFIG = {
186217
186256
  CLIENT_ID: "app_EMoamEEZ73f0CkXaXp7hrann",
186218
- AUTHORIZE_URL: "https://auth.openai.com/authorize",
186257
+ ISSUER: "https://auth.openai.com",
186258
+ AUTHORIZE_URL: "https://auth.openai.com/oauth/authorize",
186219
186259
  TOKEN_URL: "https://auth.openai.com/oauth/token",
186220
- AUDIENCE: "https://api.openai.com/v1",
186221
- SCOPES: ["openid", "profile", "email", "offline_access"],
186260
+ SCOPES: ["openid", "profile", "email", "offline_access", "api.connectors.read", "api.connectors.invoke"],
186222
186261
  CALLBACK_PORT: 1455,
186223
186262
  REDIRECT_URI: "http://localhost:1455/auth/callback"
186224
186263
  };
@@ -186396,13 +186435,27 @@ async function getOpenAIClient({
186396
186435
  apiKey
186397
186436
  }) {
186398
186437
  let resolvedKey = apiKey || process.env.OPENAI_API_KEY || "";
186438
+ let isOAuthChatgpt = false;
186439
+ let chatgptAccountId;
186399
186440
  if (!resolvedKey) {
186400
186441
  try {
186401
- const { getOpenAIAccessToken: getOpenAIAccessToken2 } = await Promise.resolve().then(() => (init_openai_oauth(), exports_openai_oauth));
186442
+ const { getOpenAIAccessToken: getOpenAIAccessToken2, loadOpenAITokens: loadOpenAITokens2 } = await Promise.resolve().then(() => (init_openai_oauth(), exports_openai_oauth));
186402
186443
  resolvedKey = await getOpenAIAccessToken2() || "";
186444
+ if (resolvedKey) {
186445
+ isOAuthChatgpt = true;
186446
+ try {
186447
+ const tokens = loadOpenAITokens2();
186448
+ const token = tokens?.access_token || resolvedKey;
186449
+ const parts = token.split(".");
186450
+ if (parts.length === 3) {
186451
+ const payload = JSON.parse(Buffer.from(parts[1].replace(/-/g, "+").replace(/_/g, "/"), "base64").toString());
186452
+ chatgptAccountId = payload?.["https://api.openai.com/auth"]?.chatgpt_account_id;
186453
+ }
186454
+ } catch {}
186455
+ }
186403
186456
  } catch {}
186404
186457
  }
186405
- const baseURL = process.env.OPENAI_BASE_URL || "https://api.openai.com/v1";
186458
+ const baseURL = process.env.OPENAI_BASE_URL || (isOAuthChatgpt ? "https://chatgpt.com/backend-api/codex" : "https://api.openai.com/v1");
186406
186459
  const timeout = parseInt(process.env.API_TIMEOUT_MS || String(600000), 10);
186407
186460
  if (_cachedOpenAIClient && _cachedOpenAIClient.apiKey === resolvedKey) {
186408
186461
  return _cachedOpenAIClient;
@@ -186411,9 +186464,11 @@ async function getOpenAIClient({
186411
186464
  apiKey: resolvedKey,
186412
186465
  baseURL,
186413
186466
  timeout,
186467
+ isOAuthChatgpt,
186468
+ chatgptAccountId,
186414
186469
  fetch: globalThis.fetch
186415
186470
  };
186416
- logForDebugging(`[API:openai] Client created, baseURL=${baseURL}, auth=${resolvedKey ? process.env.OPENAI_API_KEY ? "api-key" : "oauth" : "none"}`);
186471
+ logForDebugging(`[API:openai] Client created, baseURL=${baseURL}, auth=${resolvedKey ? isOAuthChatgpt ? "oauth-chatgpt" : "api-key" : "none"}${chatgptAccountId ? ", account=" + chatgptAccountId : ""}`);
186417
186472
  return _cachedOpenAIClient;
186418
186473
  }
186419
186474
  function buildFetch(fetchOverride, source) {
@@ -204606,7 +204661,7 @@ var init_metadata = __esm(() => {
204606
204661
  isClaudeAiAuth: isClaudeAISubscriber(),
204607
204662
  version: "2.1.88-rebuild",
204608
204663
  versionBase: getVersionBase(),
204609
- buildTime: "2026-04-01T10:24:01.092Z",
204664
+ buildTime: "2026-04-01T19:52:43.844Z",
204610
204665
  deploymentEnvironment: env4.detectDeploymentEnvironment(),
204611
204666
  ...isEnvTruthy(process.env.GITHUB_ACTIONS) && {
204612
204667
  githubEventName: process.env.GITHUB_EVENT_NAME,
@@ -592892,7 +592947,7 @@ function getAnthropicEnvMetadata() {
592892
592947
  function getBuildAgeMinutes() {
592893
592948
  if (false)
592894
592949
  ;
592895
- const buildTime = new Date("2026-04-01T10:24:01.092Z").getTime();
592950
+ const buildTime = new Date("2026-04-01T19:52:43.844Z").getTime();
592896
592951
  if (isNaN(buildTime))
592897
592952
  return;
592898
592953
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -595237,12 +595292,16 @@ async function* queryModelOpenAI(messages, systemPrompt, thinkingConfig, tools,
595237
595292
  for (let attempt = 0;attempt <= MAX_RETRIES4; attempt++) {
595238
595293
  if (signal.aborted)
595239
595294
  return;
595295
+ const headers = {
595296
+ "Content-Type": "application/json",
595297
+ Authorization: `Bearer ${client3.apiKey}`
595298
+ };
595299
+ if (client3.isOAuthChatgpt && client3.chatgptAccountId) {
595300
+ headers["chatgpt-account-id"] = client3.chatgptAccountId;
595301
+ }
595240
595302
  response = await client3.fetch(`${client3.baseURL}/responses`, {
595241
595303
  method: "POST",
595242
- headers: {
595243
- "Content-Type": "application/json",
595244
- Authorization: `Bearer ${client3.apiKey}`
595245
- },
595304
+ headers,
595246
595305
  body: JSON.stringify(params),
595247
595306
  signal
595248
595307
  });
@@ -679463,7 +679522,7 @@ var init_bridge_kick = __esm(() => {
679463
679522
  var call56 = async () => {
679464
679523
  return {
679465
679524
  type: "text",
679466
- value: `${"2.1.88-rebuild"} (built ${"2026-04-01T10:24:01.092Z"})`
679525
+ value: `${"2.1.88-rebuild"} (built ${"2026-04-01T19:52:43.844Z"})`
679467
679526
  };
679468
679527
  }, version6, version_default;
679469
679528
  var init_version = __esm(() => {
@@ -699243,12 +699302,16 @@ async function verifyApiKey(apiKey, isNonInteractiveSession) {
699243
699302
  const client3 = await getOpenAIClient({ apiKey: apiKey || undefined, maxRetries: 0 });
699244
699303
  if (!client3.apiKey)
699245
699304
  return false;
699305
+ const verifyHeaders = {
699306
+ "Content-Type": "application/json",
699307
+ Authorization: `Bearer ${client3.apiKey}`
699308
+ };
699309
+ if (client3.isOAuthChatgpt && client3.chatgptAccountId) {
699310
+ verifyHeaders["chatgpt-account-id"] = client3.chatgptAccountId;
699311
+ }
699246
699312
  const resp = await client3.fetch(`${client3.baseURL}/responses`, {
699247
699313
  method: "POST",
699248
- headers: {
699249
- "Content-Type": "application/json",
699250
- Authorization: `Bearer ${client3.apiKey}`
699251
- },
699314
+ headers: verifyHeaders,
699252
699315
  body: JSON.stringify({
699253
699316
  model: resolveOpenAIModel2(getSmallFastModel()),
699254
699317
  input: "test",
@@ -777469,4 +777532,4 @@ async function main2() {
777469
777532
  }
777470
777533
  main2();
777471
777534
 
777472
- //# debugId=699B3904C01ABC6A64756E2164756E21
777535
+ //# debugId=AD792C044104FF2164756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-openai",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "Claude Code CLI with OpenAI GPT-5.4 backend support",
5
5
  "type": "module",
6
6
  "bin": {