codex-multi-auth 0.1.0 → 0.1.2

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 (124) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +223 -98
  3. package/assets/readme-hero.svg +31 -31
  4. package/config/README.md +30 -87
  5. package/config/{opencode-legacy.json → codex-legacy.json} +571 -571
  6. package/config/{opencode-modern.json → codex-modern.json} +241 -239
  7. package/config/{minimal-opencode.json → minimal-codex.json} +15 -13
  8. package/config/schema/config.schema.json +21 -0
  9. package/dist/index.d.ts +5 -5
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +23 -20
  12. package/dist/index.js.map +1 -1
  13. package/dist/lib/accounts.d.ts +1 -1
  14. package/dist/lib/accounts.d.ts.map +1 -1
  15. package/dist/lib/auth/auth.d.ts +1 -1
  16. package/dist/lib/auth/auth.js +1 -1
  17. package/dist/lib/cli.d.ts +1 -1
  18. package/dist/lib/cli.js +4 -4
  19. package/dist/lib/cli.js.map +1 -1
  20. package/dist/lib/codex-manager/settings-hub.d.ts +6 -0
  21. package/dist/lib/codex-manager/settings-hub.d.ts.map +1 -0
  22. package/dist/lib/codex-manager/settings-hub.js +1786 -0
  23. package/dist/lib/codex-manager/settings-hub.js.map +1 -0
  24. package/dist/lib/codex-manager.d.ts.map +1 -1
  25. package/dist/lib/codex-manager.js +5 -1637
  26. package/dist/lib/codex-manager.js.map +1 -1
  27. package/dist/lib/config.d.ts.map +1 -1
  28. package/dist/lib/config.js +20 -11
  29. package/dist/lib/config.js.map +1 -1
  30. package/dist/lib/context-overflow.d.ts +1 -1
  31. package/dist/lib/context-overflow.js +11 -11
  32. package/dist/lib/oauth-success.html +1 -1
  33. package/dist/lib/prompts/codex-host-bridge.d.ts +19 -0
  34. package/dist/lib/prompts/codex-host-bridge.d.ts.map +1 -0
  35. package/dist/lib/prompts/{codex-opencode-bridge.js → codex-host-bridge.js} +143 -143
  36. package/dist/lib/prompts/codex-host-bridge.js.map +1 -0
  37. package/dist/lib/prompts/codex.d.ts +2 -2
  38. package/dist/lib/prompts/codex.d.ts.map +1 -1
  39. package/dist/lib/prompts/codex.js +3 -3
  40. package/dist/lib/prompts/host-codex-prompt.d.ts +25 -0
  41. package/dist/lib/prompts/host-codex-prompt.d.ts.map +1 -0
  42. package/dist/lib/prompts/{opencode-codex.js → host-codex-prompt.js} +136 -47
  43. package/dist/lib/prompts/host-codex-prompt.js.map +1 -0
  44. package/dist/lib/recovery/storage.d.ts +2 -2
  45. package/dist/lib/recovery/storage.js +2 -2
  46. package/dist/lib/recovery/types.d.ts +1 -1
  47. package/dist/lib/recovery/types.js +1 -1
  48. package/dist/lib/recovery.d.ts +1 -1
  49. package/dist/lib/recovery.d.ts.map +1 -1
  50. package/dist/lib/recovery.js +1 -4
  51. package/dist/lib/recovery.js.map +1 -1
  52. package/dist/lib/request/fetch-helpers.d.ts +3 -3
  53. package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
  54. package/dist/lib/request/fetch-helpers.js +6 -2
  55. package/dist/lib/request/fetch-helpers.js.map +1 -1
  56. package/dist/lib/request/helpers/input-utils.d.ts +2 -2
  57. package/dist/lib/request/helpers/input-utils.d.ts.map +1 -1
  58. package/dist/lib/request/helpers/input-utils.js +14 -14
  59. package/dist/lib/request/helpers/input-utils.js.map +1 -1
  60. package/dist/lib/request/helpers/model-map.d.ts +2 -2
  61. package/dist/lib/request/helpers/model-map.js +2 -2
  62. package/dist/lib/request/request-transformer.d.ts +12 -12
  63. package/dist/lib/request/request-transformer.d.ts.map +1 -1
  64. package/dist/lib/request/request-transformer.js +23 -24
  65. package/dist/lib/request/request-transformer.js.map +1 -1
  66. package/dist/lib/runtime-paths.d.ts +4 -4
  67. package/dist/lib/runtime-paths.d.ts.map +1 -1
  68. package/dist/lib/runtime-paths.js +57 -13
  69. package/dist/lib/runtime-paths.js.map +1 -1
  70. package/dist/lib/storage/paths.d.ts +11 -0
  71. package/dist/lib/storage/paths.d.ts.map +1 -1
  72. package/dist/lib/storage/paths.js +167 -5
  73. package/dist/lib/storage/paths.js.map +1 -1
  74. package/dist/lib/storage.d.ts +1 -0
  75. package/dist/lib/storage.d.ts.map +1 -1
  76. package/dist/lib/storage.js +290 -81
  77. package/dist/lib/storage.js.map +1 -1
  78. package/dist/lib/tools/hashline-tools.d.ts +1 -1
  79. package/dist/lib/tools/hashline-tools.d.ts.map +1 -1
  80. package/dist/lib/tools/hashline-tools.js +1 -1
  81. package/dist/lib/tools/hashline-tools.js.map +1 -1
  82. package/dist/lib/types.d.ts +1 -1
  83. package/dist/lib/types.d.ts.map +1 -1
  84. package/dist/lib/ui/copy.d.ts +6 -6
  85. package/dist/lib/ui/copy.js +6 -6
  86. package/dist/lib/ui/copy.js.map +1 -1
  87. package/node_modules/@codex-ai/plugin/dist/index.d.ts +2 -0
  88. package/node_modules/@codex-ai/plugin/dist/index.js +2 -0
  89. package/node_modules/@codex-ai/plugin/dist/tool.d.ts +42 -0
  90. package/node_modules/@codex-ai/plugin/dist/tool.js +29 -0
  91. package/node_modules/@codex-ai/plugin/package.json +9 -0
  92. package/package.json +30 -16
  93. package/scripts/audit-dev-allowlist.js +128 -128
  94. package/scripts/bench-format/{opencode.mjs → codex-host.mjs} +206 -205
  95. package/scripts/bench-format/hashline-v2.mjs +642 -642
  96. package/scripts/bench-format/models.mjs +111 -105
  97. package/scripts/bench-format/render.mjs +496 -496
  98. package/scripts/bench-format/stats.mjs +54 -54
  99. package/scripts/bench-format/tasks.mjs +151 -151
  100. package/scripts/benchmark-edit-formats.mjs +1162 -1161
  101. package/scripts/benchmark-render-dashboard.mjs +49 -49
  102. package/scripts/codex.js +40 -2
  103. package/scripts/copy-oauth-success.js +37 -37
  104. package/scripts/install-codex-auth-utils.js +49 -0
  105. package/scripts/{install-opencode-codex-auth.js → install-codex-auth.js} +220 -193
  106. package/scripts/repo-hygiene.js +320 -0
  107. package/scripts/test-all-models.sh +7 -7
  108. package/scripts/test-model-matrix.js +475 -423
  109. package/scripts/validate-model-map.sh +7 -7
  110. package/vendor/codex-ai-plugin/dist/index.d.ts +2 -0
  111. package/vendor/codex-ai-plugin/dist/index.js +2 -0
  112. package/vendor/codex-ai-plugin/dist/tool.d.ts +42 -0
  113. package/vendor/codex-ai-plugin/dist/tool.js +29 -0
  114. package/vendor/codex-ai-plugin/package.json +9 -0
  115. package/vendor/codex-ai-sdk/dist/index.d.ts +4 -0
  116. package/vendor/codex-ai-sdk/dist/index.js +2 -0
  117. package/vendor/codex-ai-sdk/package.json +8 -0
  118. package/assets/opencode-logo-ornate-dark.svg +0 -18
  119. package/dist/lib/prompts/codex-opencode-bridge.d.ts +0 -19
  120. package/dist/lib/prompts/codex-opencode-bridge.d.ts.map +0 -1
  121. package/dist/lib/prompts/codex-opencode-bridge.js.map +0 -1
  122. package/dist/lib/prompts/opencode-codex.d.ts +0 -25
  123. package/dist/lib/prompts/opencode-codex.d.ts.map +0 -1
  124. package/dist/lib/prompts/opencode-codex.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * OpenAI ChatGPT (Codex) OAuth Authentication Plugin for opencode
2
+ * OpenAI ChatGPT (Codex) OAuth Authentication Plugin for Codex CLI host runtime
3
3
  *
4
4
  * COMPLIANCE NOTICE:
5
5
  * This plugin uses OpenAI's official OAuth authentication flow (the same method
@@ -22,7 +22,7 @@
22
22
  * @repository https://github.com/ndycode/codex-multi-auth
23
23
 
24
24
  */
25
- import { tool } from "@opencode-ai/plugin/tool";
25
+ import { tool } from "@codex-ai/plugin/tool";
26
26
  import { createAuthorizationFlow, exchangeAuthorizationCode, parseAuthorizationInput, redactOAuthUrlForLog, REDIRECT_URI, } from "./lib/auth/auth.js";
27
27
  import { queuedRefresh } from "./lib/refresh-queue.js";
28
28
  import { openBrowserUrl } from "./lib/auth/browser.js";
@@ -34,7 +34,7 @@ import { initLogger, logRequest, logDebug, logInfo, logWarn, logError, setCorrel
34
34
  import { checkAndNotify } from "./lib/auto-update-checker.js";
35
35
  import { handleContextOverflow } from "./lib/context-overflow.js";
36
36
  import { AccountManager, getAccountIdCandidates, extractAccountEmail, extractAccountId, formatAccountLabel, formatCooldown, formatWaitTime, sanitizeEmail, selectBestAccountCandidate, shouldUpdateAccountIdFromToken, resolveRequestAccountId, parseRateLimitReason, lookupCodexCliTokensByEmail, isCodexCliSyncEnabled, } from "./lib/accounts.js";
37
- import { getStoragePath, loadAccounts, saveAccounts, withAccountStorageTransaction, clearAccounts, setStoragePath, exportAccounts, importAccounts, loadFlaggedAccounts, saveFlaggedAccounts, clearFlaggedAccounts, StorageError, formatStorageErrorHint, setStorageBackupEnabled, } from "./lib/storage.js";
37
+ import { getStoragePath, loadAccounts, saveAccounts, withAccountStorageTransaction, clearAccounts, setStoragePath, exportAccounts, importAccounts, loadFlaggedAccounts, saveFlaggedAccounts, clearFlaggedAccounts, normalizeEmailKey, StorageError, formatStorageErrorHint, setStorageBackupEnabled, } from "./lib/storage.js";
38
38
  import { createCodexHeaders, extractRequestUrl, handleErrorResponse, handleSuccessResponse, getUnsupportedCodexModelInfo, resolveUnsupportedCodexFallbackModel, refreshAndUpdateToken, rewriteUrlForCodex, shouldRefreshToken, transformRequestForCodex, } from "./lib/request/fetch-helpers.js";
39
39
  import { applyFastSessionDefaults } from "./lib/request/request-transformer.js";
40
40
  import { getRateLimitBackoff, RATE_LIMIT_SHORT_RETRY_THRESHOLD_MS, resetRateLimitBackoff, } from "./lib/request/rate-limit-backoff.js";
@@ -52,14 +52,14 @@ import { buildTableHeader, buildTableRow } from "./lib/table-formatter.js";
52
52
  import { setUiRuntimeOptions } from "./lib/ui/runtime.js";
53
53
  import { paintUiText, formatUiBadge, formatUiHeader, formatUiItem, formatUiKeyValue, formatUiSection } from "./lib/ui/format.js";
54
54
  import { getModelFamily, getCodexInstructions, MODEL_FAMILIES, prewarmCodexInstructions, } from "./lib/prompts/codex.js";
55
- import { prewarmOpenCodeCodexPrompt } from "./lib/prompts/opencode-codex.js";
55
+ import { prewarmHostCodexPrompt } from "./lib/prompts/host-codex-prompt.js";
56
56
  import { createSessionRecoveryHook, isRecoverableError, detectErrorType, getRecoveryToastContent, } from "./lib/recovery.js";
57
57
  import { createHashlineEditTool, createHashlineReadTool, } from "./lib/tools/hashline-tools.js";
58
58
  import { registerCleanup } from "./lib/shutdown.js";
59
59
  /**
60
- * OpenAI Codex OAuth authentication plugin for opencode
60
+ * OpenAI Codex OAuth authentication plugin for Codex CLI host runtime
61
61
  *
62
- * This plugin enables opencode to use OpenAI's Codex backend via ChatGPT Plus/Pro
62
+ * This plugin enables the host runtime to use OpenAI's Codex backend via ChatGPT Plus/Pro
63
63
  * OAuth authentication, allowing users to leverage their ChatGPT subscription
64
64
  * instead of OpenAI Platform API credits.
65
65
  *
@@ -211,7 +211,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
211
211
  validate: (input) => {
212
212
  const parsed = parseAuthorizationInput(input);
213
213
  if (!parsed.code) {
214
- return "No authorization code found. Paste the full callback URL (e.g., http://localhost:1455/auth/callback?code=...)";
214
+ return `No authorization code found. Paste the full callback URL (e.g., ${REDIRECT_URI}?code=...)`;
215
215
  }
216
216
  if (!parsed.state) {
217
217
  return "Missing OAuth state. Paste the full callback URL including both code and state parameters.";
@@ -296,8 +296,9 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
296
296
  if (account.accountId) {
297
297
  indexByAccountId.set(account.accountId, i);
298
298
  }
299
- if (account.email) {
300
- indexByEmail.set(account.email, i);
299
+ const emailKey = normalizeEmailKey(account.email);
300
+ if (emailKey) {
301
+ indexByEmail.set(emailKey, i);
301
302
  }
302
303
  }
303
304
  for (const result of results) {
@@ -343,7 +344,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
343
344
  continue;
344
345
  const oldToken = existing.refreshToken;
345
346
  const oldEmail = existing.email;
346
- const nextEmail = accountEmail ?? existing.email;
347
+ const nextEmail = accountEmail ?? sanitizeEmail(existing.email);
347
348
  const nextAccountId = accountId ?? existing.accountId;
348
349
  const nextAccountIdSource = accountId ? accountIdSource ?? existing.accountIdSource : existing.accountIdSource;
349
350
  const nextAccountLabel = accountLabel ?? existing.accountLabel;
@@ -365,11 +366,13 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
365
366
  if (accountId) {
366
367
  indexByAccountId.set(accountId, existingIndex);
367
368
  }
368
- if (oldEmail && oldEmail !== nextEmail) {
369
- indexByEmail.delete(oldEmail);
369
+ const oldEmailKey = normalizeEmailKey(oldEmail);
370
+ const nextEmailKey = normalizeEmailKey(nextEmail);
371
+ if (oldEmailKey && oldEmailKey !== nextEmailKey) {
372
+ indexByEmail.delete(oldEmailKey);
370
373
  }
371
- if (nextEmail) {
372
- indexByEmail.set(nextEmail, existingIndex);
374
+ if (nextEmailKey) {
375
+ indexByEmail.set(nextEmailKey, existingIndex);
373
376
  }
374
377
  }
375
378
  if (accounts.length === 0)
@@ -426,7 +429,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
426
429
  return storage;
427
430
  const skipHydrate = process.env.VITEST_WORKER_ID !== undefined ||
428
431
  process.env.NODE_ENV === "test" ||
429
- process.env.OPENCODE_SKIP_EMAIL_HYDRATE === "1";
432
+ process.env.CODEX_SKIP_EMAIL_HYDRATE === "1";
430
433
  if (skipHydrate)
431
434
  return storage;
432
435
  const accountsCopy = storage.accounts.map((account) => account ? { ...account } : account);
@@ -710,12 +713,12 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
710
713
  * This function:
711
714
  * 1. Validates OAuth authentication
712
715
  * 2. Loads multi-account pool from disk (fallback to current auth)
713
- * 3. Loads user configuration from opencode.json
716
+ * 3. Loads user configuration from runtime model config
714
717
  * 4. Fetches Codex system instructions from GitHub (cached)
715
718
  * 5. Returns SDK configuration with custom fetch implementation
716
719
  *
717
720
  * @param getAuth - Function to retrieve current auth state
718
- * @param provider - Provider configuration from opencode.json
721
+ * @param provider - Provider configuration from runtime model config
719
722
  * @returns SDK configuration object or empty object for non-OAuth auth
720
723
  */
721
724
  async loader(getAuth, provider) {
@@ -731,7 +734,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
731
734
  return {};
732
735
  }
733
736
  // Prefer multi-account auth metadata when available, but still handle
734
- // plain OAuth credentials (for OpenCode versions that inject internal
737
+ // plain OAuth credentials (for legacy runtime versions that inject internal
735
738
  // Codex auth first and omit the multiAccount marker).
736
739
  const authWithMulti = auth;
737
740
  if (!authWithMulti.multiAccount) {
@@ -824,7 +827,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
824
827
  const configuredModels = Object.keys(userConfig.models ?? {});
825
828
  prewarmCodexInstructions(configuredModels);
826
829
  if (codexMode) {
827
- prewarmOpenCodeCodexPrompt();
830
+ prewarmHostCodexPrompt();
828
831
  }
829
832
  }
830
833
  const recoveryHook = sessionRecoveryEnabled
@@ -2470,7 +2473,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
2470
2473
  },
2471
2474
  tool: {
2472
2475
  edit: createHashlineEditTool(),
2473
- // OpenCode v1.2.x exposes apply_patch (not edit) to the model.
2476
+ // Legacy runtime v1.2.x exposes apply_patch (not edit) to the model.
2474
2477
  // Register the same hashline-capable implementation under both names.
2475
2478
  apply_patch: createHashlineEditTool(),
2476
2479
  hashline_read: createHashlineReadTool(),