codex-multi-auth 2.16.0 → 2.17.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 (303) hide show
  1. package/.codex-plugin/plugin.json +9 -9
  2. package/LICENSE +21 -21
  3. package/README.md +487 -463
  4. package/assets/codex-multi-auth-icon.svg +39 -39
  5. package/assets/readme-hero.svg +31 -31
  6. package/config/README.md +31 -31
  7. package/config/codex-legacy.json +1221 -1221
  8. package/config/codex-modern.json +423 -423
  9. package/config/minimal-codex.json +15 -15
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +8 -3
  12. package/dist/lib/account-policy.d.ts +4 -0
  13. package/dist/lib/account-policy.d.ts.map +1 -1
  14. package/dist/lib/account-policy.js +8 -0
  15. package/dist/lib/accounts/rate-limits.d.ts.map +1 -1
  16. package/dist/lib/accounts/rate-limits.js +2 -0
  17. package/dist/lib/accounts.d.ts +15 -3
  18. package/dist/lib/accounts.d.ts.map +1 -1
  19. package/dist/lib/accounts.js +231 -30
  20. package/dist/lib/api-route-store.d.ts +24 -0
  21. package/dist/lib/api-route-store.d.ts.map +1 -0
  22. package/dist/lib/api-route-store.js +145 -0
  23. package/dist/lib/auth/account-access.d.ts +115 -0
  24. package/dist/lib/auth/account-access.d.ts.map +1 -0
  25. package/dist/lib/auth/account-access.js +214 -0
  26. package/dist/lib/auth/token-utils.d.ts +54 -1
  27. package/dist/lib/auth/token-utils.d.ts.map +1 -1
  28. package/dist/lib/auth/token-utils.js +92 -7
  29. package/dist/lib/cli.d.ts +1 -1
  30. package/dist/lib/cli.d.ts.map +1 -1
  31. package/dist/lib/cli.js +4 -0
  32. package/dist/lib/codex-cli/state.d.ts +7 -0
  33. package/dist/lib/codex-cli/state.d.ts.map +1 -1
  34. package/dist/lib/codex-cli/state.js +18 -0
  35. package/dist/lib/codex-cli/writer.d.ts.map +1 -1
  36. package/dist/lib/codex-cli/writer.js +60 -8
  37. package/dist/lib/codex-manager/account-manager-commands.d.ts.map +1 -1
  38. package/dist/lib/codex-manager/account-manager-commands.js +1 -0
  39. package/dist/lib/codex-manager/account-pool-write.d.ts +3 -1
  40. package/dist/lib/codex-manager/account-pool-write.d.ts.map +1 -1
  41. package/dist/lib/codex-manager/account-pool-write.js +4 -0
  42. package/dist/lib/codex-manager/api-login-menu.d.ts +14 -0
  43. package/dist/lib/codex-manager/api-login-menu.d.ts.map +1 -0
  44. package/dist/lib/codex-manager/api-login-menu.js +224 -0
  45. package/dist/lib/codex-manager/commands/account.d.ts.map +1 -1
  46. package/dist/lib/codex-manager/commands/account.js +27 -0
  47. package/dist/lib/codex-manager/commands/best.d.ts.map +1 -1
  48. package/dist/lib/codex-manager/commands/best.js +6 -2
  49. package/dist/lib/codex-manager/commands/check.d.ts +7 -1
  50. package/dist/lib/codex-manager/commands/check.d.ts.map +1 -1
  51. package/dist/lib/codex-manager/commands/check.js +24 -3
  52. package/dist/lib/codex-manager/commands/forecast.d.ts +1 -1
  53. package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -1
  54. package/dist/lib/codex-manager/commands/forecast.js +7 -3
  55. package/dist/lib/codex-manager/commands/report.d.ts.map +1 -1
  56. package/dist/lib/codex-manager/commands/report.js +5 -1
  57. package/dist/lib/codex-manager/commands/resets.d.ts +2 -0
  58. package/dist/lib/codex-manager/commands/resets.d.ts.map +1 -0
  59. package/dist/lib/codex-manager/commands/resets.js +67 -0
  60. package/dist/lib/codex-manager/commands/rotation.d.ts +2 -2
  61. package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -1
  62. package/dist/lib/codex-manager/commands/rotation.js +63 -12
  63. package/dist/lib/codex-manager/commands/status.d.ts +12 -1
  64. package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
  65. package/dist/lib/codex-manager/commands/status.js +166 -22
  66. package/dist/lib/codex-manager/commands/uninstall.js +1 -1
  67. package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +1 -1
  68. package/dist/lib/codex-manager/formatters/quota-formatters.js +3 -2
  69. package/dist/lib/codex-manager/health-check.d.ts +3 -0
  70. package/dist/lib/codex-manager/health-check.d.ts.map +1 -1
  71. package/dist/lib/codex-manager/health-check.js +57 -7
  72. package/dist/lib/codex-manager/help.d.ts.map +1 -1
  73. package/dist/lib/codex-manager/help.js +4 -2
  74. package/dist/lib/codex-manager/login-flow.d.ts.map +1 -1
  75. package/dist/lib/codex-manager/login-flow.js +69 -7
  76. package/dist/lib/codex-manager/login-menu-data.d.ts.map +1 -1
  77. package/dist/lib/codex-manager/login-menu-data.js +21 -8
  78. package/dist/lib/codex-manager/login-oauth.d.ts +3 -0
  79. package/dist/lib/codex-manager/login-oauth.d.ts.map +1 -1
  80. package/dist/lib/codex-manager/login-oauth.js +6 -1
  81. package/dist/lib/codex-manager/login-workspace-choice.d.ts +11 -0
  82. package/dist/lib/codex-manager/login-workspace-choice.d.ts.map +1 -0
  83. package/dist/lib/codex-manager/login-workspace-choice.js +37 -0
  84. package/dist/lib/codex-manager/persist-selected-account.d.ts.map +1 -1
  85. package/dist/lib/codex-manager/persist-selected-account.js +2 -1
  86. package/dist/lib/codex-manager/quota-cache-helpers.d.ts +7 -1
  87. package/dist/lib/codex-manager/quota-cache-helpers.d.ts.map +1 -1
  88. package/dist/lib/codex-manager/quota-cache-helpers.js +34 -19
  89. package/dist/lib/codex-manager/repair-commands.d.ts +13 -0
  90. package/dist/lib/codex-manager/repair-commands.d.ts.map +1 -1
  91. package/dist/lib/codex-manager/repair-commands.js +144 -9
  92. package/dist/lib/codex-manager.d.ts.map +1 -1
  93. package/dist/lib/codex-manager.js +25 -6
  94. package/dist/lib/concurrency.d.ts +3 -0
  95. package/dist/lib/concurrency.d.ts.map +1 -0
  96. package/dist/lib/concurrency.js +31 -0
  97. package/dist/lib/context-budget-response.js +8 -8
  98. package/dist/lib/context-overflow.js +10 -10
  99. package/dist/lib/model-route-policy.d.ts +52 -0
  100. package/dist/lib/model-route-policy.d.ts.map +1 -0
  101. package/dist/lib/model-route-policy.js +159 -0
  102. package/dist/lib/oauth-success.html +125 -125
  103. package/dist/lib/policy/runtime-policy.d.ts +1 -0
  104. package/dist/lib/policy/runtime-policy.d.ts.map +1 -1
  105. package/dist/lib/policy/runtime-policy.js +3 -0
  106. package/dist/lib/preemptive-quota-scheduler.d.ts +2 -0
  107. package/dist/lib/preemptive-quota-scheduler.d.ts.map +1 -1
  108. package/dist/lib/preemptive-quota-scheduler.js +4 -0
  109. package/dist/lib/prompts/codex-host-bridge.js +138 -138
  110. package/dist/lib/prompts/codex.js +79 -79
  111. package/dist/lib/quota-cache.d.ts +7 -3
  112. package/dist/lib/quota-cache.d.ts.map +1 -1
  113. package/dist/lib/quota-cache.js +91 -59
  114. package/dist/lib/quota-probe.d.ts +5 -0
  115. package/dist/lib/quota-probe.d.ts.map +1 -1
  116. package/dist/lib/quota-probe.js +26 -2
  117. package/dist/lib/quota-readiness.d.ts +7 -2
  118. package/dist/lib/quota-readiness.d.ts.map +1 -1
  119. package/dist/lib/quota-readiness.js +25 -4
  120. package/dist/lib/request/client-cancellation.d.ts +5 -0
  121. package/dist/lib/request/client-cancellation.d.ts.map +1 -0
  122. package/dist/lib/request/client-cancellation.js +7 -0
  123. package/dist/lib/request/response-outcome.d.ts +25 -0
  124. package/dist/lib/request/response-outcome.d.ts.map +1 -0
  125. package/dist/lib/request/response-outcome.js +49 -0
  126. package/dist/lib/request/stream-failover-runtime.d.ts +2 -1
  127. package/dist/lib/request/stream-failover-runtime.d.ts.map +1 -1
  128. package/dist/lib/request/stream-failover-runtime.js +29 -10
  129. package/dist/lib/runtime/account-check.d.ts.map +1 -1
  130. package/dist/lib/runtime/account-check.js +2 -8
  131. package/dist/lib/runtime/account-model-catalog.d.ts +64 -0
  132. package/dist/lib/runtime/account-model-catalog.d.ts.map +1 -0
  133. package/dist/lib/runtime/account-model-catalog.js +154 -0
  134. package/dist/lib/runtime/account-pool.d.ts +3 -1
  135. package/dist/lib/runtime/account-pool.d.ts.map +1 -1
  136. package/dist/lib/runtime/account-pool.js +4 -0
  137. package/dist/lib/runtime/account-reset-credits.d.ts +42 -0
  138. package/dist/lib/runtime/account-reset-credits.d.ts.map +1 -0
  139. package/dist/lib/runtime/account-reset-credits.js +82 -0
  140. package/dist/lib/runtime/api-model-capabilities.d.ts +30 -0
  141. package/dist/lib/runtime/api-model-capabilities.d.ts.map +1 -0
  142. package/dist/lib/runtime/api-model-capabilities.js +434 -0
  143. package/dist/lib/runtime/api-model-runtime.d.ts +42 -0
  144. package/dist/lib/runtime/api-model-runtime.d.ts.map +1 -0
  145. package/dist/lib/runtime/api-model-runtime.js +358 -0
  146. package/dist/lib/runtime/app-bind.d.ts +19 -1
  147. package/dist/lib/runtime/app-bind.d.ts.map +1 -1
  148. package/dist/lib/runtime/app-bind.js +89 -11
  149. package/dist/lib/runtime/automatic-account-checks.d.ts +35 -0
  150. package/dist/lib/runtime/automatic-account-checks.d.ts.map +1 -0
  151. package/dist/lib/runtime/automatic-account-checks.js +140 -0
  152. package/dist/lib/runtime/automatic-subscription-checks.d.ts +7 -0
  153. package/dist/lib/runtime/automatic-subscription-checks.d.ts.map +1 -0
  154. package/dist/lib/runtime/automatic-subscription-checks.js +54 -0
  155. package/dist/lib/runtime/catalog-capabilities.d.ts +8 -0
  156. package/dist/lib/runtime/catalog-capabilities.d.ts.map +1 -0
  157. package/dist/lib/runtime/catalog-capabilities.js +61 -0
  158. package/dist/lib/runtime/inference-activity.d.ts +15 -0
  159. package/dist/lib/runtime/inference-activity.d.ts.map +1 -0
  160. package/dist/lib/runtime/inference-activity.js +95 -0
  161. package/dist/lib/runtime/model-discovery-status.d.ts +100 -0
  162. package/dist/lib/runtime/model-discovery-status.d.ts.map +1 -0
  163. package/dist/lib/runtime/model-discovery-status.js +387 -0
  164. package/dist/lib/runtime/native-account-storage.d.ts +11 -0
  165. package/dist/lib/runtime/native-account-storage.d.ts.map +1 -0
  166. package/dist/lib/runtime/native-account-storage.js +50 -0
  167. package/dist/lib/runtime/native-account-sync.d.ts +19 -0
  168. package/dist/lib/runtime/native-account-sync.d.ts.map +1 -0
  169. package/dist/lib/runtime/native-account-sync.js +62 -0
  170. package/dist/lib/runtime/native-binding-lock.d.ts +3 -0
  171. package/dist/lib/runtime/native-binding-lock.d.ts.map +1 -0
  172. package/dist/lib/runtime/native-binding-lock.js +5 -0
  173. package/dist/lib/runtime/native-client-auth.d.ts +3 -0
  174. package/dist/lib/runtime/native-client-auth.d.ts.map +1 -0
  175. package/dist/lib/runtime/native-client-auth.js +42 -0
  176. package/dist/lib/runtime/native-provider-config.d.ts +4 -0
  177. package/dist/lib/runtime/native-provider-config.d.ts.map +1 -0
  178. package/dist/lib/runtime/native-provider-config.js +52 -0
  179. package/dist/lib/runtime/native-rate-limits.d.ts +18 -0
  180. package/dist/lib/runtime/native-rate-limits.d.ts.map +1 -0
  181. package/dist/lib/runtime/native-rate-limits.js +135 -0
  182. package/dist/lib/runtime/reset-credit-routing.d.ts +41 -0
  183. package/dist/lib/runtime/reset-credit-routing.d.ts.map +1 -0
  184. package/dist/lib/runtime/reset-credit-routing.js +66 -0
  185. package/dist/lib/runtime/reset-credits.d.ts +101 -0
  186. package/dist/lib/runtime/reset-credits.d.ts.map +1 -0
  187. package/dist/lib/runtime/reset-credits.js +162 -0
  188. package/dist/lib/runtime/response-output-history.d.ts +17 -0
  189. package/dist/lib/runtime/response-output-history.d.ts.map +1 -0
  190. package/dist/lib/runtime/response-output-history.js +85 -0
  191. package/dist/lib/runtime/responses-websocket.d.ts +31 -0
  192. package/dist/lib/runtime/responses-websocket.d.ts.map +1 -0
  193. package/dist/lib/runtime/responses-websocket.js +636 -0
  194. package/dist/lib/runtime/resume-picker.d.ts +41 -0
  195. package/dist/lib/runtime/resume-picker.d.ts.map +1 -0
  196. package/dist/lib/runtime/resume-picker.js +169 -0
  197. package/dist/lib/runtime/rotation-account-selection.d.ts +6 -0
  198. package/dist/lib/runtime/rotation-account-selection.d.ts.map +1 -1
  199. package/dist/lib/runtime/rotation-account-selection.js +63 -0
  200. package/dist/lib/runtime/rotation-proxy-state.d.ts +33 -0
  201. package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
  202. package/dist/lib/runtime/rotation-server-types.d.ts +18 -0
  203. package/dist/lib/runtime/rotation-server-types.d.ts.map +1 -1
  204. package/dist/lib/runtime/runtime-capability-failures.d.ts +14 -0
  205. package/dist/lib/runtime/runtime-capability-failures.d.ts.map +1 -0
  206. package/dist/lib/runtime/runtime-capability-failures.js +76 -0
  207. package/dist/lib/runtime/runtime-observability.d.ts +7 -0
  208. package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
  209. package/dist/lib/runtime/runtime-observability.js +42 -2
  210. package/dist/lib/runtime/subscription-first-use.d.ts +10 -0
  211. package/dist/lib/runtime/subscription-first-use.d.ts.map +1 -0
  212. package/dist/lib/runtime/subscription-first-use.js +64 -0
  213. package/dist/lib/runtime/subscription-quota-event.d.ts +6 -0
  214. package/dist/lib/runtime/subscription-quota-event.d.ts.map +1 -0
  215. package/dist/lib/runtime/subscription-quota-event.js +31 -0
  216. package/dist/lib/runtime/subscription-quota-order.d.ts +17 -0
  217. package/dist/lib/runtime/subscription-quota-order.d.ts.map +1 -0
  218. package/dist/lib/runtime/subscription-quota-order.js +31 -0
  219. package/dist/lib/runtime/workspace-model-scopes.d.ts +15 -0
  220. package/dist/lib/runtime/workspace-model-scopes.d.ts.map +1 -0
  221. package/dist/lib/runtime/workspace-model-scopes.js +34 -0
  222. package/dist/lib/runtime-constants.d.ts +3 -0
  223. package/dist/lib/runtime-constants.d.ts.map +1 -1
  224. package/dist/lib/runtime-constants.js +5 -0
  225. package/dist/lib/runtime-paths.d.ts.map +1 -1
  226. package/dist/lib/runtime-paths.js +4 -1
  227. package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
  228. package/dist/lib/runtime-rotation-proxy.js +852 -42
  229. package/dist/lib/schemas.d.ts +20 -0
  230. package/dist/lib/schemas.d.ts.map +1 -1
  231. package/dist/lib/schemas.js +3 -0
  232. package/dist/lib/storage/credential-sidecars.d.ts +13 -0
  233. package/dist/lib/storage/credential-sidecars.d.ts.map +1 -0
  234. package/dist/lib/storage/credential-sidecars.js +52 -0
  235. package/dist/lib/storage/file-lock.d.ts +9 -0
  236. package/dist/lib/storage/file-lock.d.ts.map +1 -0
  237. package/dist/lib/storage/file-lock.js +186 -0
  238. package/dist/lib/storage/flagged-storage.d.ts.map +1 -1
  239. package/dist/lib/storage/flagged-storage.js +12 -0
  240. package/dist/lib/storage/path-state.d.ts +2 -0
  241. package/dist/lib/storage/path-state.d.ts.map +1 -1
  242. package/dist/lib/storage/path-state.js +9 -0
  243. package/dist/lib/storage/paths.js +4 -4
  244. package/dist/lib/storage/pending-auth.d.ts +18 -0
  245. package/dist/lib/storage/pending-auth.d.ts.map +1 -0
  246. package/dist/lib/storage/pending-auth.js +155 -0
  247. package/dist/lib/storage/public-types.d.ts +13 -0
  248. package/dist/lib/storage/public-types.d.ts.map +1 -1
  249. package/dist/lib/storage/record-identity.d.ts +16 -0
  250. package/dist/lib/storage/record-identity.d.ts.map +1 -0
  251. package/dist/lib/storage/record-identity.js +16 -0
  252. package/dist/lib/storage/snapshot-merge.d.ts +16 -0
  253. package/dist/lib/storage/snapshot-merge.d.ts.map +1 -0
  254. package/dist/lib/storage/snapshot-merge.js +206 -0
  255. package/dist/lib/storage/transactions.d.ts.map +1 -1
  256. package/dist/lib/storage/transactions.js +5 -4
  257. package/dist/lib/storage.d.ts +6 -0
  258. package/dist/lib/storage.d.ts.map +1 -1
  259. package/dist/lib/storage.js +77 -7
  260. package/dist/lib/ui/auth-menu-builder.d.ts +2 -0
  261. package/dist/lib/ui/auth-menu-builder.d.ts.map +1 -1
  262. package/dist/lib/ui/auth-menu-builder.js +1 -0
  263. package/dist/lib/ui/auth-menu.d.ts.map +1 -1
  264. package/dist/lib/ui/auth-menu.js +1 -0
  265. package/dist/lib/ui/check-progress.d.ts +8 -0
  266. package/dist/lib/ui/check-progress.d.ts.map +1 -0
  267. package/dist/lib/ui/check-progress.js +30 -0
  268. package/dist/lib/ui/format.d.ts +3 -1
  269. package/dist/lib/ui/format.d.ts.map +1 -1
  270. package/dist/lib/ui/format.js +8 -0
  271. package/dist/lib/ui/ui-copy.d.ts +2 -2
  272. package/dist/lib/ui/ui-copy.js +2 -2
  273. package/dist/lib/usage/pricing.js +2 -2
  274. package/dist/lib/usage/usage-extraction.d.ts +3 -1
  275. package/dist/lib/usage/usage-extraction.d.ts.map +1 -1
  276. package/dist/lib/usage/usage-extraction.js +46 -9
  277. package/node_modules/@codex-ai/plugin/dist/index.d.ts +2 -2
  278. package/node_modules/@codex-ai/plugin/dist/index.js +2 -2
  279. package/node_modules/@codex-ai/plugin/dist/tool.d.ts +42 -42
  280. package/node_modules/@codex-ai/plugin/dist/tool.js +29 -29
  281. package/node_modules/@codex-ai/plugin/package.json +9 -9
  282. package/node_modules/@codex-ai/sdk/dist/index.d.ts +4 -4
  283. package/node_modules/@codex-ai/sdk/dist/index.js +2 -2
  284. package/node_modules/@codex-ai/sdk/package.json +8 -8
  285. package/package.json +200 -197
  286. package/scripts/codex-app-launcher.js +653 -653
  287. package/scripts/codex-app-router.js +373 -366
  288. package/scripts/codex-bin-resolver.js +313 -281
  289. package/scripts/codex-multi-auth.js +59 -59
  290. package/scripts/codex-routing.js +62 -61
  291. package/scripts/codex.js +6642 -6564
  292. package/scripts/install-codex-auth-utils.js +213 -213
  293. package/scripts/mcodex.js +367 -367
  294. package/scripts/postinstall.js +114 -114
  295. package/scripts/preuninstall.js +265 -265
  296. package/vendor/codex-ai-plugin/dist/index.d.ts +2 -2
  297. package/vendor/codex-ai-plugin/dist/index.js +2 -2
  298. package/vendor/codex-ai-plugin/dist/tool.d.ts +42 -42
  299. package/vendor/codex-ai-plugin/dist/tool.js +29 -29
  300. package/vendor/codex-ai-plugin/package.json +9 -9
  301. package/vendor/codex-ai-sdk/dist/index.d.ts +4 -4
  302. package/vendor/codex-ai-sdk/dist/index.js +2 -2
  303. package/vendor/codex-ai-sdk/package.json +8 -8
@@ -1,281 +1,313 @@
1
- import { spawnSync } from "node:child_process";
2
- import { existsSync, realpathSync } from "node:fs";
3
- import { createRequire } from "node:module";
4
- import { basename, delimiter, dirname, extname, isAbsolute, join, relative } from "node:path";
5
- import process from "node:process";
6
- import { fileURLToPath } from "node:url";
7
-
8
- function isJavaScriptEntryPath(candidate) {
9
- const extension = extname(candidate).toLowerCase();
10
- return extension === ".js" || extension === ".mjs" || extension === ".cjs";
11
- }
12
-
13
- function createResolvedCodexBin(path) {
14
- return {
15
- path,
16
- launchWithNode: isJavaScriptEntryPath(path),
17
- };
18
- }
19
-
20
- function normalizeResolvedPath(candidatePath, realpathSyncImpl) {
21
- try {
22
- return realpathSyncImpl(candidatePath);
23
- } catch {
24
- return candidatePath;
25
- }
26
- }
27
-
28
- // Defense-in-depth self-recursion guard. The exact-realpath check only blocks
29
- // the wrapper's own codex.js (the POSIX symlink case). If the wrapper were ever
30
- // exposed as a native codex/codex.exe sitting alongside it, that exact-path
31
- // check would miss it. Skipping any candidate that resolves inside the
32
- // wrapper's own directory closes that latent self-loop.
33
- function isWithinDirectory(candidatePath, directoryPath, realpathSyncImpl) {
34
- if (!directoryPath) return false;
35
- const resolvedCandidate = normalizeResolvedPath(candidatePath, realpathSyncImpl);
36
- const relativePath = relative(directoryPath, resolvedCandidate);
37
- return (
38
- relativePath === "" ||
39
- (!relativePath.startsWith("..") && !isAbsolute(relativePath))
40
- );
41
- }
42
-
43
- function resolveWrapperScriptPath(moduleUrl, realpathSyncImpl) {
44
- return normalizeResolvedPath(fileURLToPath(moduleUrl), realpathSyncImpl);
45
- }
46
-
47
- const DEFAULT_WRAPPER_MODULE_URL = new URL("./codex.js", import.meta.url).href;
48
-
49
- function defaultResolvePackageBin(moduleUrl) {
50
- try {
51
- const require = createRequire(moduleUrl);
52
- return require.resolve("@openai/codex/bin/codex.js");
53
- } catch {
54
- return null;
55
- }
56
- }
57
-
58
- function resolveWindowsCmdPath(env) {
59
- const comSpec = (env.ComSpec ?? env.COMSPEC ?? "").trim();
60
- if (comSpec.length > 0) return comSpec;
61
-
62
- const systemRoot = (env.SystemRoot ?? env.SYSTEMROOT ?? "").trim();
63
- if (systemRoot.length > 0) {
64
- return `${systemRoot.replace(/[\\/]+$/, "")}\\System32\\cmd.exe`;
65
- }
66
-
67
- return "cmd.exe";
68
- }
69
-
70
- export function splitPathEntries(pathValue) {
71
- if (typeof pathValue !== "string" || pathValue.trim().length === 0) {
72
- return [];
73
- }
74
- return pathValue
75
- .split(delimiter)
76
- .map((entry) => entry.trim())
77
- .filter((entry) => entry.length > 0);
78
- }
79
-
80
- function resolvePathExecutableName(platform) {
81
- return platform === "win32" ? "codex.exe" : "codex";
82
- }
83
-
84
- function resolveCandidateExecutableNames(platform) {
85
- if (platform !== "win32") {
86
- return [resolvePathExecutableName(platform)];
87
- }
88
- return ["codex.exe", "codex"];
89
- }
90
-
91
- function resolveCodexExecutableFromPath(
92
- pathEntries,
93
- platform,
94
- existsSyncImpl,
95
- selfScriptPath,
96
- realpathSyncImpl,
97
- ) {
98
- for (const entry of pathEntries) {
99
- for (const executableName of resolveCandidateExecutableNames(platform)) {
100
- const candidate = join(entry, executableName);
101
- if (!existsSyncImpl(candidate)) {
102
- continue;
103
- }
104
- if (
105
- selfScriptPath &&
106
- normalizeResolvedPath(candidate, realpathSyncImpl) === selfScriptPath
107
- ) {
108
- continue;
109
- }
110
- if (
111
- selfScriptPath &&
112
- isWithinDirectory(candidate, dirname(selfScriptPath), realpathSyncImpl)
113
- ) {
114
- continue;
115
- }
116
- return candidate;
117
- }
118
- }
119
- return null;
120
- }
121
-
122
- function normalizeWhereOutput(stdout) {
123
- return stdout
124
- .split(/\r?\n/)
125
- .map((line) => line.trim())
126
- .filter((line) => line.length > 0);
127
- }
128
-
129
- function resolveCodexExecutableFromSystemPath(
130
- env,
131
- platform,
132
- spawnSyncImpl,
133
- existsSyncImpl,
134
- selfScriptPath,
135
- realpathSyncImpl,
136
- ) {
137
- const pathEntries = splitPathEntries(env.PATH ?? env.Path ?? "");
138
- const fromEnvPath = resolveCodexExecutableFromPath(
139
- pathEntries,
140
- platform,
141
- existsSyncImpl,
142
- selfScriptPath,
143
- realpathSyncImpl,
144
- );
145
- if (fromEnvPath) {
146
- return fromEnvPath;
147
- }
148
-
149
- try {
150
- const lookupResult =
151
- platform === "win32"
152
- ? spawnSyncImpl(resolveWindowsCmdPath(env), ["/d", "/s", "/c", "where codex"], {
153
- encoding: "utf8",
154
- env,
155
- stdio: ["ignore", "pipe", "ignore"],
156
- timeout: 5000,
157
- windowsHide: true,
158
- })
159
- : spawnSyncImpl("which", ["codex"], {
160
- encoding: "utf8",
161
- env,
162
- stdio: ["ignore", "pipe", "ignore"],
163
- timeout: 5000,
164
- });
165
- if (lookupResult.status !== 0) {
166
- return null;
167
- }
168
- for (const candidate of normalizeWhereOutput(lookupResult.stdout)) {
169
- if (!existsSyncImpl(candidate)) {
170
- continue;
171
- }
172
- if (
173
- selfScriptPath &&
174
- normalizeResolvedPath(candidate, realpathSyncImpl) === selfScriptPath
175
- ) {
176
- continue;
177
- }
178
- if (
179
- selfScriptPath &&
180
- isWithinDirectory(candidate, dirname(selfScriptPath), realpathSyncImpl)
181
- ) {
182
- continue;
183
- }
184
- const fileName = basename(candidate).toLowerCase();
185
- if (fileName === "codex" || fileName === "codex.exe") {
186
- return candidate;
187
- }
188
- }
189
- } catch {
190
- // Ignore and fall through.
191
- }
192
-
193
- return null;
194
- }
195
-
196
- export function resolveRealCodexBin(options = {}) {
197
- const {
198
- env = process.env,
199
- argv = process.argv,
200
- platform = process.platform,
201
- moduleUrl = DEFAULT_WRAPPER_MODULE_URL,
202
- existsSyncImpl = existsSync,
203
- realpathSyncImpl = realpathSync,
204
- spawnSyncImpl = spawnSync,
205
- resolvePackageBin = defaultResolvePackageBin,
206
- } = options;
207
-
208
- const override = (env.CODEX_MULTI_AUTH_REAL_CODEX_BIN ?? "").trim();
209
- if (override.length > 0) {
210
- if (existsSyncImpl(override)) return createResolvedCodexBin(override);
211
- return null;
212
- }
213
-
214
- const resolved = resolvePackageBin(moduleUrl);
215
- if (typeof resolved === "string" && resolved.length > 0 && existsSyncImpl(resolved)) {
216
- return createResolvedCodexBin(resolved);
217
- }
218
-
219
- const searchRoots = [];
220
- const scriptDir = dirname(fileURLToPath(moduleUrl));
221
- searchRoots.push(join(scriptDir, "..", ".."));
222
-
223
- const invokedScript = argv[1];
224
- if (typeof invokedScript === "string" && invokedScript.length > 0) {
225
- searchRoots.push(join(dirname(invokedScript), "..", ".."));
226
- }
227
-
228
- const npmPrefix = (env.npm_config_prefix ?? env.PREFIX ?? "").trim();
229
- if (npmPrefix.length > 0) {
230
- searchRoots.push(join(npmPrefix, "node_modules"));
231
- searchRoots.push(join(npmPrefix, "lib", "node_modules"));
232
- }
233
-
234
- for (const root of searchRoots) {
235
- const candidate = join(root, "@openai", "codex", "bin", "codex.js");
236
- if (existsSyncImpl(candidate)) return createResolvedCodexBin(candidate);
237
- }
238
-
239
- try {
240
- const rootResult =
241
- platform === "win32"
242
- ? spawnSyncImpl(resolveWindowsCmdPath(env), ["/d", "/s", "/c", "npm root -g"], {
243
- encoding: "utf8",
244
- env,
245
- stdio: ["ignore", "pipe", "ignore"],
246
- timeout: 5000,
247
- windowsHide: true,
248
- })
249
- : spawnSyncImpl("npm", ["root", "-g"], {
250
- encoding: "utf8",
251
- env,
252
- stdio: ["ignore", "pipe", "ignore"],
253
- timeout: 5000,
254
- });
255
- if (rootResult.status === 0) {
256
- const globalRoot = rootResult.stdout.trim();
257
- if (globalRoot.length > 0) {
258
- const globalBin = join(globalRoot, "@openai", "codex", "bin", "codex.js");
259
- if (existsSyncImpl(globalBin)) return createResolvedCodexBin(globalBin);
260
- }
261
- }
262
- } catch {
263
- // Ignore and fall through to null.
264
- }
265
-
266
- const selfScriptPath = resolveWrapperScriptPath(moduleUrl, realpathSyncImpl);
267
-
268
- const nativeCodexBin = resolveCodexExecutableFromSystemPath(
269
- env,
270
- platform,
271
- spawnSyncImpl,
272
- existsSyncImpl,
273
- selfScriptPath,
274
- realpathSyncImpl,
275
- );
276
- if (nativeCodexBin) {
277
- return createResolvedCodexBin(nativeCodexBin);
278
- }
279
-
280
- return null;
281
- }
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync, realpathSync } from "node:fs";
3
+ import { createRequire } from "node:module";
4
+ import { basename, dirname, extname, isAbsolute, join, posix, relative, win32 } from "node:path";
5
+ import process from "node:process";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ function isJavaScriptEntryPath(candidate) {
9
+ const extension = extname(candidate).toLowerCase();
10
+ return extension === ".js" || extension === ".mjs" || extension === ".cjs";
11
+ }
12
+
13
+ function createResolvedCodexBin(path) {
14
+ return {
15
+ path,
16
+ launchWithNode: isJavaScriptEntryPath(path),
17
+ };
18
+ }
19
+
20
+ function normalizeResolvedPath(candidatePath, realpathSyncImpl) {
21
+ try {
22
+ return realpathSyncImpl(candidatePath);
23
+ } catch {
24
+ return candidatePath;
25
+ }
26
+ }
27
+
28
+ // Defense-in-depth self-recursion guard. The exact-realpath check only blocks
29
+ // the wrapper's own codex.js (the POSIX symlink case). If the wrapper were ever
30
+ // exposed as a native codex/codex.exe sitting alongside it, that exact-path
31
+ // check would miss it. Skipping any candidate that resolves inside the
32
+ // wrapper's own directory closes that latent self-loop.
33
+ function isWithinDirectory(candidatePath, directoryPath, realpathSyncImpl) {
34
+ if (!directoryPath) return false;
35
+ const resolvedCandidate = normalizeResolvedPath(candidatePath, realpathSyncImpl);
36
+ const relativePath = relative(directoryPath, resolvedCandidate);
37
+ return (
38
+ relativePath === "" ||
39
+ (!relativePath.startsWith("..") && !isAbsolute(relativePath))
40
+ );
41
+ }
42
+
43
+ function resolveWrapperScriptPath(moduleUrl, realpathSyncImpl) {
44
+ return normalizeResolvedPath(fileURLToPath(moduleUrl), realpathSyncImpl);
45
+ }
46
+
47
+ const DEFAULT_WRAPPER_MODULE_URL = new URL("./codex.js", import.meta.url).href;
48
+
49
+ function defaultResolvePackageBin(moduleUrl) {
50
+ try {
51
+ const require = createRequire(moduleUrl);
52
+ return require.resolve("@openai/codex/bin/codex.js");
53
+ } catch {
54
+ return null;
55
+ }
56
+ }
57
+
58
+ // spawn() without a shell cannot run these on Windows: `.cmd`/`.bat` are
59
+ // EINVAL, `.ps1` is not an executable image, and an extensionless file
60
+ // (npm's `#!/bin/sh` shim) is ENOENT even when it is a real PE image. Going through cmd.exe instead would put every
61
+ // forwarded argument through cmd's quoting rules.
62
+ export function isWindowsShimPath(candidatePath) {
63
+ const extension = win32.extname(candidatePath).toLowerCase();
64
+ return extension === "" || extension === ".cmd" || extension === ".bat" || extension === ".ps1";
65
+ }
66
+
67
+ // npm's Windows shims sit in the prefix dir and run
68
+ // `<prefix>\node_modules\@openai\codex\bin\codex.js`.
69
+ export function resolveWindowsShimPackageEntry(shimPath, existsSyncImpl = existsSync) {
70
+ const entry = win32.join(
71
+ win32.dirname(shimPath),
72
+ "node_modules",
73
+ "@openai",
74
+ "codex",
75
+ "bin",
76
+ "codex.js",
77
+ );
78
+ return existsSyncImpl(entry) ? entry : null;
79
+ }
80
+
81
+ function resolveWindowsCmdPath(env) {
82
+ const comSpec = (env.ComSpec ?? env.COMSPEC ?? "").trim();
83
+ if (comSpec.length > 0) return comSpec;
84
+
85
+ const systemRoot = (env.SystemRoot ?? env.SYSTEMROOT ?? "").trim();
86
+ if (systemRoot.length > 0) {
87
+ return `${systemRoot.replace(/[\\/]+$/, "")}\\System32\\cmd.exe`;
88
+ }
89
+
90
+ return "cmd.exe";
91
+ }
92
+
93
+ export function splitPathEntries(pathValue, platform = process.platform) {
94
+ if (typeof pathValue !== "string" || pathValue.trim().length === 0) {
95
+ return [];
96
+ }
97
+ return pathValue
98
+ .split(platform === "win32" ? ";" : ":")
99
+ .map((entry) => entry.trim())
100
+ .filter((entry) => entry.length > 0);
101
+ }
102
+
103
+ function resolvePathExecutableName(platform) {
104
+ return platform === "win32" ? "codex.exe" : "codex";
105
+ }
106
+
107
+ function resolveCandidateExecutableNames(platform) {
108
+ if (platform !== "win32") {
109
+ return [resolvePathExecutableName(platform)];
110
+ }
111
+ // npm on Windows puts `codex.cmd` plus an extensionless `#!/bin/sh` shim in
112
+ // the prefix dir and the package under `<prefix>\node_modules`. Neither shim
113
+ // can be spawned without a shell (`.cmd` is EINVAL, the sh script ENOENT),
114
+ // so launch the package entry the shims point at before falling back to an
115
+ // extensionless `codex`.
116
+ return ["codex.exe", win32.join("node_modules", "@openai", "codex", "bin", "codex.js"), "codex"];
117
+ }
118
+
119
+ function resolveCodexExecutableFromPath(
120
+ pathEntries,
121
+ platform,
122
+ existsSyncImpl,
123
+ selfScriptPath,
124
+ realpathSyncImpl,
125
+ ) {
126
+ for (const entry of pathEntries) {
127
+ for (const executableName of resolveCandidateExecutableNames(platform)) {
128
+ const candidate = (platform === "win32" ? win32 : posix).join(entry, executableName);
129
+ if (!existsSyncImpl(candidate)) {
130
+ continue;
131
+ }
132
+ if (
133
+ selfScriptPath &&
134
+ normalizeResolvedPath(candidate, realpathSyncImpl) === selfScriptPath
135
+ ) {
136
+ continue;
137
+ }
138
+ if (
139
+ selfScriptPath &&
140
+ isWithinDirectory(candidate, dirname(selfScriptPath), realpathSyncImpl)
141
+ ) {
142
+ continue;
143
+ }
144
+ return candidate;
145
+ }
146
+ }
147
+ return null;
148
+ }
149
+
150
+ function normalizeWhereOutput(stdout) {
151
+ return stdout
152
+ .split(/\r?\n/)
153
+ .map((line) => line.trim())
154
+ .filter((line) => line.length > 0);
155
+ }
156
+
157
+ function resolveCodexExecutableFromSystemPath(
158
+ env,
159
+ platform,
160
+ spawnSyncImpl,
161
+ existsSyncImpl,
162
+ selfScriptPath,
163
+ realpathSyncImpl,
164
+ ) {
165
+ const pathEntries = splitPathEntries(env.PATH ?? env.Path ?? "", platform);
166
+ const fromEnvPath = resolveCodexExecutableFromPath(
167
+ pathEntries,
168
+ platform,
169
+ existsSyncImpl,
170
+ selfScriptPath,
171
+ realpathSyncImpl,
172
+ );
173
+ if (fromEnvPath) {
174
+ return fromEnvPath;
175
+ }
176
+
177
+ try {
178
+ const lookupResult =
179
+ platform === "win32"
180
+ ? spawnSyncImpl(resolveWindowsCmdPath(env), ["/d", "/s", "/c", "where codex"], {
181
+ encoding: "utf8",
182
+ env,
183
+ stdio: ["ignore", "pipe", "ignore"],
184
+ timeout: 5000,
185
+ windowsHide: true,
186
+ })
187
+ : spawnSyncImpl("which", ["codex"], {
188
+ encoding: "utf8",
189
+ env,
190
+ stdio: ["ignore", "pipe", "ignore"],
191
+ timeout: 5000,
192
+ });
193
+ if (lookupResult.status !== 0) {
194
+ return null;
195
+ }
196
+ for (const candidate of normalizeWhereOutput(lookupResult.stdout)) {
197
+ if (!existsSyncImpl(candidate)) {
198
+ continue;
199
+ }
200
+ if (
201
+ selfScriptPath &&
202
+ normalizeResolvedPath(candidate, realpathSyncImpl) === selfScriptPath
203
+ ) {
204
+ continue;
205
+ }
206
+ if (
207
+ selfScriptPath &&
208
+ isWithinDirectory(candidate, dirname(selfScriptPath), realpathSyncImpl)
209
+ ) {
210
+ continue;
211
+ }
212
+ const fileName = basename(candidate).toLowerCase();
213
+ if (fileName === "codex" || fileName === "codex.exe") {
214
+ return candidate;
215
+ }
216
+ }
217
+ } catch {
218
+ // Ignore and fall through.
219
+ }
220
+
221
+ return null;
222
+ }
223
+
224
+ export function resolveRealCodexBin(options = {}) {
225
+ const {
226
+ env = process.env,
227
+ argv = process.argv,
228
+ platform = process.platform,
229
+ moduleUrl = DEFAULT_WRAPPER_MODULE_URL,
230
+ existsSyncImpl = existsSync,
231
+ realpathSyncImpl = realpathSync,
232
+ spawnSyncImpl = spawnSync,
233
+ resolvePackageBin = defaultResolvePackageBin,
234
+ } = options;
235
+
236
+ const override = (env.CODEX_MULTI_AUTH_REAL_CODEX_BIN ?? "").trim();
237
+ if (override.length > 0) {
238
+ if (!existsSyncImpl(override)) return null;
239
+ if (platform === "win32" && isWindowsShimPath(override)) {
240
+ const entry = resolveWindowsShimPackageEntry(override, existsSyncImpl);
241
+ return entry ? createResolvedCodexBin(entry) : null;
242
+ }
243
+ return createResolvedCodexBin(override);
244
+ }
245
+
246
+ const resolved = resolvePackageBin(moduleUrl);
247
+ if (typeof resolved === "string" && resolved.length > 0 && existsSyncImpl(resolved)) {
248
+ return createResolvedCodexBin(resolved);
249
+ }
250
+
251
+ const searchRoots = [];
252
+ const scriptDir = dirname(fileURLToPath(moduleUrl));
253
+ searchRoots.push(join(scriptDir, "..", ".."));
254
+
255
+ const invokedScript = argv[1];
256
+ if (typeof invokedScript === "string" && invokedScript.length > 0) {
257
+ searchRoots.push(join(dirname(invokedScript), "..", ".."));
258
+ }
259
+
260
+ const npmPrefix = (env.npm_config_prefix ?? env.PREFIX ?? "").trim();
261
+ if (npmPrefix.length > 0) {
262
+ searchRoots.push(join(npmPrefix, "node_modules"));
263
+ searchRoots.push(join(npmPrefix, "lib", "node_modules"));
264
+ }
265
+
266
+ for (const root of searchRoots) {
267
+ const candidate = join(root, "@openai", "codex", "bin", "codex.js");
268
+ if (existsSyncImpl(candidate)) return createResolvedCodexBin(candidate);
269
+ }
270
+
271
+ try {
272
+ const rootResult =
273
+ platform === "win32"
274
+ ? spawnSyncImpl(resolveWindowsCmdPath(env), ["/d", "/s", "/c", "npm root -g"], {
275
+ encoding: "utf8",
276
+ env,
277
+ stdio: ["ignore", "pipe", "ignore"],
278
+ timeout: 5000,
279
+ windowsHide: true,
280
+ })
281
+ : spawnSyncImpl("npm", ["root", "-g"], {
282
+ encoding: "utf8",
283
+ env,
284
+ stdio: ["ignore", "pipe", "ignore"],
285
+ timeout: 5000,
286
+ });
287
+ if (rootResult.status === 0) {
288
+ const globalRoot = rootResult.stdout.trim();
289
+ if (globalRoot.length > 0) {
290
+ const globalBin = join(globalRoot, "@openai", "codex", "bin", "codex.js");
291
+ if (existsSyncImpl(globalBin)) return createResolvedCodexBin(globalBin);
292
+ }
293
+ }
294
+ } catch {
295
+ // Ignore and fall through to null.
296
+ }
297
+
298
+ const selfScriptPath = resolveWrapperScriptPath(moduleUrl, realpathSyncImpl);
299
+
300
+ const nativeCodexBin = resolveCodexExecutableFromSystemPath(
301
+ env,
302
+ platform,
303
+ spawnSyncImpl,
304
+ existsSyncImpl,
305
+ selfScriptPath,
306
+ realpathSyncImpl,
307
+ );
308
+ if (nativeCodexBin) {
309
+ return createResolvedCodexBin(nativeCodexBin);
310
+ }
311
+
312
+ return null;
313
+ }