@darkjd/opencode-openai-codex-auth 4.10.1

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 (90) hide show
  1. package/LICENSE +37 -0
  2. package/README.md +137 -0
  3. package/assets/opencode-logo-ornate-dark.svg +18 -0
  4. package/assets/readme-hero.svg +31 -0
  5. package/dist/index.d.ts +42 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +226 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/lib/auth/auth.d.ts +43 -0
  10. package/dist/lib/auth/auth.d.ts.map +1 -0
  11. package/dist/lib/auth/auth.js +163 -0
  12. package/dist/lib/auth/auth.js.map +1 -0
  13. package/dist/lib/auth/browser.d.ts +17 -0
  14. package/dist/lib/auth/browser.d.ts.map +1 -0
  15. package/dist/lib/auth/browser.js +76 -0
  16. package/dist/lib/auth/browser.js.map +1 -0
  17. package/dist/lib/auth/server.d.ts +10 -0
  18. package/dist/lib/auth/server.d.ts.map +1 -0
  19. package/dist/lib/auth/server.js +78 -0
  20. package/dist/lib/auth/server.js.map +1 -0
  21. package/dist/lib/auth/v2-storage.d.ts +35 -0
  22. package/dist/lib/auth/v2-storage.d.ts.map +1 -0
  23. package/dist/lib/auth/v2-storage.js +79 -0
  24. package/dist/lib/auth/v2-storage.js.map +1 -0
  25. package/dist/lib/config.d.ts +17 -0
  26. package/dist/lib/config.d.ts.map +1 -0
  27. package/dist/lib/config.js +51 -0
  28. package/dist/lib/config.js.map +1 -0
  29. package/dist/lib/constants.d.ts +69 -0
  30. package/dist/lib/constants.d.ts.map +1 -0
  31. package/dist/lib/constants.js +69 -0
  32. package/dist/lib/constants.js.map +1 -0
  33. package/dist/lib/logger.d.ts +21 -0
  34. package/dist/lib/logger.d.ts.map +1 -0
  35. package/dist/lib/logger.js +77 -0
  36. package/dist/lib/logger.js.map +1 -0
  37. package/dist/lib/oauth-success.html +712 -0
  38. package/dist/lib/prompts/codex-opencode-bridge.d.ts +19 -0
  39. package/dist/lib/prompts/codex-opencode-bridge.d.ts.map +1 -0
  40. package/dist/lib/prompts/codex-opencode-bridge.js +157 -0
  41. package/dist/lib/prompts/codex-opencode-bridge.js.map +1 -0
  42. package/dist/lib/prompts/codex.d.ts +27 -0
  43. package/dist/lib/prompts/codex.d.ts.map +1 -0
  44. package/dist/lib/prompts/codex.js +256 -0
  45. package/dist/lib/prompts/codex.js.map +1 -0
  46. package/dist/lib/prompts/opencode-codex.d.ts +21 -0
  47. package/dist/lib/prompts/opencode-codex.d.ts.map +1 -0
  48. package/dist/lib/prompts/opencode-codex.js +91 -0
  49. package/dist/lib/prompts/opencode-codex.js.map +1 -0
  50. package/dist/lib/request/fetch-helpers.d.ts +73 -0
  51. package/dist/lib/request/fetch-helpers.d.ts.map +1 -0
  52. package/dist/lib/request/fetch-helpers.js +231 -0
  53. package/dist/lib/request/fetch-helpers.js.map +1 -0
  54. package/dist/lib/request/helpers/input-utils.d.ts +6 -0
  55. package/dist/lib/request/helpers/input-utils.d.ts.map +1 -0
  56. package/dist/lib/request/helpers/input-utils.js +174 -0
  57. package/dist/lib/request/helpers/input-utils.js.map +1 -0
  58. package/dist/lib/request/helpers/model-map.d.ts +28 -0
  59. package/dist/lib/request/helpers/model-map.d.ts.map +1 -0
  60. package/dist/lib/request/helpers/model-map.js +134 -0
  61. package/dist/lib/request/helpers/model-map.js.map +1 -0
  62. package/dist/lib/request/helpers/model-registry-data.d.ts +86 -0
  63. package/dist/lib/request/helpers/model-registry-data.d.ts.map +1 -0
  64. package/dist/lib/request/helpers/model-registry-data.js +293 -0
  65. package/dist/lib/request/helpers/model-registry-data.js.map +1 -0
  66. package/dist/lib/request/helpers/model-registry.d.ts +45 -0
  67. package/dist/lib/request/helpers/model-registry.d.ts.map +1 -0
  68. package/dist/lib/request/helpers/model-registry.js +208 -0
  69. package/dist/lib/request/helpers/model-registry.js.map +1 -0
  70. package/dist/lib/request/helpers/skill-catalog.d.ts +59 -0
  71. package/dist/lib/request/helpers/skill-catalog.d.ts.map +1 -0
  72. package/dist/lib/request/helpers/skill-catalog.js +81 -0
  73. package/dist/lib/request/helpers/skill-catalog.js.map +1 -0
  74. package/dist/lib/request/request-transformer.d.ts +81 -0
  75. package/dist/lib/request/request-transformer.d.ts.map +1 -0
  76. package/dist/lib/request/request-transformer.js +477 -0
  77. package/dist/lib/request/request-transformer.js.map +1 -0
  78. package/dist/lib/request/response-handler.d.ts +14 -0
  79. package/dist/lib/request/response-handler.d.ts.map +1 -0
  80. package/dist/lib/request/response-handler.js +88 -0
  81. package/dist/lib/request/response-handler.js.map +1 -0
  82. package/dist/lib/types.d.ts +178 -0
  83. package/dist/lib/types.d.ts.map +1 -0
  84. package/dist/lib/types.js +2 -0
  85. package/dist/lib/types.js.map +1 -0
  86. package/dist/v2.d.ts +34 -0
  87. package/dist/v2.d.ts.map +1 -0
  88. package/dist/v2.js +259 -0
  89. package/dist/v2.js.map +1 -0
  90. package/package.json +87 -0
package/LICENSE ADDED
@@ -0,0 +1,37 @@
1
+ MIT License with Usage Disclaimer
2
+
3
+ Copyright (c) 2024-2025 numman-ali
4
+
5
+ USAGE NOTICE AND DISCLAIMER:
6
+ This software is provided for personal development use only. Users must comply
7
+ with OpenAI's Terms of Service (https://openai.com/policies/terms-of-use/) and
8
+ Usage Policies (https://openai.com/policies/usage-policies/) when using this
9
+ software to access OpenAI services.
10
+
11
+ The authors and contributors are not responsible for any violations of
12
+ third-party terms of service. For commercial use or production applications,
13
+ obtain proper API access from OpenAI directly through the OpenAI Platform
14
+ (https://platform.openai.com/).
15
+
16
+ This software uses OpenAI's official OAuth authentication system and is not
17
+ affiliated with, endorsed by, or sponsored by OpenAI.
18
+
19
+ ---
20
+
21
+ Permission is hereby granted, free of charge, to any person obtaining a copy
22
+ of this software and associated documentation files (the "Software"), to deal
23
+ in the Software without restriction, including without limitation the rights
24
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25
+ copies of the Software, and to permit persons to whom the Software is
26
+ furnished to do so, subject to the following conditions:
27
+
28
+ The above copyright notice, usage notice, and this permission notice shall be
29
+ included in all copies or substantial portions of the Software.
30
+
31
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ ![Image 1: opencode-openai-codex-auth](assets/readme-hero.svg)
2
+
3
+
4
+ **Originally created by [Numman Ali](https://x.com/nummanali) · Actively maintained fork by [JDis03](https://github.com/JDis03)**
5
+
6
+ > 🔀 **Fork notice**: The upstream repo ([numman-ali/opencode-openai-codex-auth](https://github.com/numman-ali/opencode-openai-codex-auth)) has had no commits since **2026-01-09** (v4.4.0) and open PRs/issues are unreviewed. This fork continues active development (new models, the data-driven model registry, bug fixes) under the same MIT license. Full credit to Numman Ali for creating the original project.
7
+
8
+ [![Twitter Follow](https://img.shields.io/twitter/follow/nummanali?style=social)](https://x.com/nummanali)
9
+ [![Tests](https://github.com/JDis03/opencode-openai-codex-auth/actions/workflows/ci.yml/badge.svg)](https://github.com/JDis03/opencode-openai-codex-auth/actions)
10
+ **OpenCode 2 + ChatGPT Codex OAuth.**
11
+ [Install](#-quick-start) · [Models](#-models) · [Configuration](#-configuration) · [Docs](#-docs)
12
+
13
+ ---
14
+ ## 💡 Philosophy
15
+ > **"One config. Every model."**
16
+ OpenCode should feel effortless. This plugin connects OpenCode 2 to ChatGPT Codex OAuth, with bundled model presets and request transformations.
17
+ ```
18
+ ┌─────────────────────────────────────────────────────────┐
19
+ │ │
20
+ │ ChatGPT OAuth → Codex backend → OpenCode │
21
+ │ Install the plugin, connect, then choose a model. │
22
+ │ │
23
+ └─────────────────────────────────────────────────────────┘
24
+ ```
25
+ ---
26
+ ## 🚀 Quick Start
27
+ ```bash
28
+ opencode plugin add @darkjd/opencode-openai-codex-auth
29
+ opencode auth login
30
+ # Choose openai → "ChatGPT Plus/Pro (Codex Auth)"
31
+ opencode run --model 'openai/gpt-6-sol#medium' "Say hello"
32
+ ```
33
+
34
+ OpenCode 2 installs packages from its `plugins` configuration. The old `npx opencode-openai-codex-auth` installer writes OpenCode 1 config and is **not** bundled with this scoped OpenCode 2 package. To remove the plugin, use `opencode plugin remove @darkjd/opencode-openai-codex-auth`. Existing OpenCode 1 users should keep their working 4.9.0 installation; the V1 entrypoint remains exported as `@darkjd/opencode-openai-codex-auth/legacy` for manual integrations.
35
+ ---
36
+ ## 🆕 OpenCode 2
37
+ OpenCode 2 uses a completely new plugin API — V1 plugins (including every release of this
38
+ package before this one) do not load at all under OpenCode 2, they fail a schema check
39
+ before any of their code runs. This package now ships a native V2 entrypoint alongside the
40
+ unchanged V1 one, auto-selected by `exports`:
41
+
42
+ - The package root (`@darkjd/opencode-openai-codex-auth`) resolves to the **V2** implementation.
43
+ - `@darkjd/opencode-openai-codex-auth/legacy` resolves to the **original V1** implementation, for
44
+ anyone still running OpenCode 1.
45
+
46
+ **How it works under V2**: OpenCode 2 ships its own built-in ChatGPT/Codex OAuth handling
47
+ for the `openai` integration (the `ChatGPT Pro/Plus (browser/headless)` methods you may
48
+ already see in `opencode auth login`) — but that native path does **not** apply Codex CLI
49
+ system instructions, the CODEX_MODE bridge prompt, model-registry-based reasoning
50
+ normalization, or the Skills/MCP passthrough this plugin has always provided. This plugin's
51
+ V2 build registers native `http.request`/`http.response` session hooks (scoped to the
52
+ `openai` provider) to keep applying all of that, plus its **own** OAuth integration method —
53
+ **ChatGPT Plus/Pro (Codex Auth)** — with a stable file-based credential store, since V2's
54
+ plugin API has no way to import an existing OAuth credential into its built-in connection
55
+ store.
56
+
57
+ **You must complete this plugin's own OAuth method once** for `openai` to route through it:
58
+ ```bash
59
+ opencode auth login
60
+ # select "openai" → "ChatGPT Plus/Pro (Codex Auth)"
61
+ ```
62
+ Merely installing the plugin (or already being logged in via OpenCode 2's native ChatGPT
63
+ methods) is not enough — an existing V1 `auth.json` credential is imported automatically as
64
+ a read-only fallback for token use, but it cannot make OpenCode 2 treat `openai` as
65
+ "actively connected" through this plugin's method; only completing that method's login flow
66
+ does. See `specs/opencode-v2-plugin-port.md` for the full root-cause investigation.
67
+ ---
68
+ ## 📦 Models
69
+ - **gpt-6-astra** (low/medium/high/xhigh/max; `gpt-6` alias) — no `none` support
70
+ - **gpt-6-sol** (none/low/medium/high/xhigh/max)
71
+ - **gpt-6-luna** (none/low/medium/high/xhigh/max)
72
+ - **gpt-5.6-sol** (none/low/medium/high/xhigh/max; `gpt-5.6` alias)
73
+ - **gpt-5.6-terra** (none/low/medium/high/xhigh/max)
74
+ - **gpt-5.6-luna** (none/low/medium/high/xhigh/max)
75
+ - **gpt-5.2** (none/low/medium/high/xhigh)
76
+ - **gpt-5.2-codex** (low/medium/high/xhigh)
77
+ - **gpt-5.1-codex-max** (low/medium/high/xhigh)
78
+ - **gpt-5.1-codex** (low/medium/high)
79
+ - **gpt-5.1-codex-mini** (medium/high)
80
+ - **gpt-5.1** (none/low/medium/high)
81
+
82
+ ### Additional GPT-6 catalog IDs
83
+
84
+ CodeNomad/OpenCode currently lists these GPT-6 variants:
85
+
86
+ - `gpt-6-sol-pro`
87
+ - `gpt-6-sol-fast`
88
+ - `gpt-6-luna-pro`
89
+ - `gpt-6-luna-fast`
90
+
91
+ These are separate model IDs, not reasoning variants. They are visible in the local OpenCode catalog, but are **not yet verified by this plugin against the ChatGPT Codex backend**. The current Codex CLI account catalog lists the base `gpt-6-sol` and `gpt-6-luna` models, but not these four IDs.
92
+
93
+ ---
94
+ ## 🧩 Configuration
95
+ OpenCode 2 installs the plugin with `opencode plugin add` and obtains its model catalog from OpenCode; no OpenCode 1 config template is needed. The repository's `config/opencode-modern.json` and `config/opencode-legacy.json` are historical **OpenCode 1 examples** and are not shipped in the scoped npm package. Do not paste their `plugin` entry into OpenCode 2.
96
+ ---
97
+ ## 🔄 Model Registry (maintainer notes)
98
+ Model normalization, reasoning capabilities, and prompt-family selection are
99
+ driven by a single data file: `lib/request/helpers/model-registry-data.ts`.
100
+ Adding support for a new OpenAI model is normally **one entry in that file**,
101
+ not a plugin-wide patch.
102
+
103
+ For even faster turnaround (no npm release required to get a brand-new model
104
+ recognized), point the plugin at a JSON overlay hosted anywhere you control:
105
+ ```json
106
+ // ~/.opencode/openai-codex-auth-config.json
107
+ { "codexMode": true, "modelRegistryUrl": "https://raw.githubusercontent.com/<you>/<repo>/main/model-registry.json" }
108
+ ```
109
+ or via `OPENCODE_CODEX_MODEL_REGISTRY_URL` (env var takes precedence). The
110
+ overlay is fetched with ETag caching (checked at most every 15 minutes) and
111
+ merged with the bundled registry; it's entirely opt-in — nothing is fetched
112
+ unless you configure a URL, and any failure silently falls back to the
113
+ bundled defaults.
114
+ ---
115
+ ## ✅ Features
116
+ - ChatGPT Plus/Pro OAuth authentication (official flow)
117
+ - Data-driven model registry: new models add cleanly, with an optional
118
+ self-hosted JSON overlay for instant updates between releases
119
+ - GPT‑5.6 Sol/Terra/Luna support, including `max` reasoning effort
120
+ - Variant system support (v1.0.210+) + legacy presets
121
+ - Multimodal input enabled for all models
122
+ - Usage‑aware errors + automatic token refresh
123
+ - **Skills + MCP parity with Anthropic sessions**: OpenCode's `<available_skills>`
124
+ catalog and `<mcp_instructions>` block now reach Codex too, instead of being
125
+ silently dropped — same capability awareness Claude sessions already had
126
+ ---
127
+ ## 📚 Docs
128
+ - Getting Started: `docs/getting-started.md`
129
+ - Configuration: `docs/configuration.md`
130
+ - Troubleshooting: `docs/troubleshooting.md`
131
+ - Architecture: `docs/development/ARCHITECTURE.md`
132
+ ---
133
+ ## ⚠️ Usage Notice
134
+ This plugin is for **personal development use** with your own ChatGPT Plus/Pro subscription.
135
+ For production or multi‑user applications, use the OpenAI Platform API.
136
+
137
+ **Built for developers who value simplicity.**
@@ -0,0 +1,18 @@
1
+ <svg width="234" height="42" viewBox="0 0 234 42" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M18 30H6V18H18V30Z" fill="#4B4646"/>
3
+ <path d="M18 12H6V30H18V12ZM24 36H0V6H24V36Z" fill="#B7B1B1"/>
4
+ <path d="M48 30H36V18H48V30Z" fill="#4B4646"/>
5
+ <path d="M36 30H48V12H36V30ZM54 36H36V42H30V6H54V36Z" fill="#B7B1B1"/>
6
+ <path d="M84 24V30H66V24H84Z" fill="#4B4646"/>
7
+ <path d="M84 24H66V30H84V36H60V6H84V24ZM66 18H78V12H66V18Z" fill="#B7B1B1"/>
8
+ <path d="M108 36H96V18H108V36Z" fill="#4B4646"/>
9
+ <path d="M108 12H96V36H90V6H108V12ZM114 36H108V12H114V36Z" fill="#B7B1B1"/>
10
+ <path d="M144 30H126V18H144V30Z" fill="#4B4646"/>
11
+ <path d="M144 12H126V30H144V36H120V6H144V12Z" fill="#F1ECEC"/>
12
+ <path d="M168 30H156V18H168V30Z" fill="#4B4646"/>
13
+ <path d="M168 12H156V30H168V12ZM174 36H150V6H174V36Z" fill="#F1ECEC"/>
14
+ <path d="M198 30H186V18H198V30Z" fill="#4B4646"/>
15
+ <path d="M198 12H186V30H198V12ZM204 36H180V6H198V0H204V36Z" fill="#F1ECEC"/>
16
+ <path d="M234 24V30H216V24H234Z" fill="#4B4646"/>
17
+ <path d="M216 12V18H228V12H216ZM234 24H216V30H234V36H210V6H234V24Z" fill="#F1ECEC"/>
18
+ </svg>
@@ -0,0 +1,31 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="300" viewBox="0 0 1200 300" role="img" aria-label="OpenCode Codex OAuth">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0%" stop-color="#0f172a" />
5
+ <stop offset="100%" stop-color="#1f2937" />
6
+ </linearGradient>
7
+ <linearGradient id="accent" x1="0" y1="0" x2="1" y2="0">
8
+ <stop offset="0%" stop-color="#38bdf8" />
9
+ <stop offset="100%" stop-color="#22d3ee" />
10
+ </linearGradient>
11
+ </defs>
12
+ <rect width="1200" height="300" rx="28" fill="url(#bg)" />
13
+ <g opacity="0.12">
14
+ <circle cx="1020" cy="70" r="120" fill="#38bdf8" />
15
+ <circle cx="150" cy="260" r="140" fill="#22d3ee" />
16
+ </g>
17
+ <g fill="none" stroke="url(#accent)" stroke-width="8" stroke-linecap="round" stroke-linejoin="round">
18
+ <path d="M160 95 L100 150 L160 205" />
19
+ <path d="M280 95 L340 150 L280 205" />
20
+ <path d="M205 80 L235 220" />
21
+ </g>
22
+ <text x="420" y="120" fill="#e2e8f0" font-size="42" font-family="'IBM Plex Sans','Segoe UI',Arial,sans-serif" font-weight="600">
23
+ OpenCode Codex OAuth
24
+ </text>
25
+ <text x="420" y="170" fill="#cbd5f5" font-size="24" font-family="'IBM Plex Sans','Segoe UI',Arial,sans-serif">
26
+ ChatGPT Plus/Pro auth for GPT-5.2 and Codex models
27
+ </text>
28
+ <text x="420" y="220" fill="#7dd3fc" font-size="18" font-family="'IBM Plex Sans','Segoe UI',Arial,sans-serif">
29
+ One-command install, modern variants, full tool support
30
+ </text>
31
+ </svg>
@@ -0,0 +1,42 @@
1
+ /**
2
+ * OpenAI ChatGPT (Codex) OAuth Authentication Plugin for opencode
3
+ *
4
+ * COMPLIANCE NOTICE:
5
+ * This plugin uses OpenAI's official OAuth authentication flow (the same method
6
+ * used by OpenAI's official Codex CLI at https://github.com/openai/codex).
7
+ *
8
+ * INTENDED USE: Personal development and coding assistance with your own
9
+ * ChatGPT Plus/Pro subscription.
10
+ *
11
+ * NOT INTENDED FOR: Commercial resale, multi-user services, high-volume
12
+ * automated extraction, or any use that violates OpenAI's Terms of Service.
13
+ *
14
+ * Users are responsible for ensuring their usage complies with:
15
+ * - OpenAI Terms of Use: https://openai.com/policies/terms-of-use/
16
+ * - OpenAI Usage Policies: https://openai.com/policies/usage-policies/
17
+ *
18
+ * For production applications, use the OpenAI Platform API: https://platform.openai.com/
19
+ *
20
+ * @license MIT with Usage Disclaimer (see LICENSE file)
21
+ * @author numman-ali
22
+ * @repository https://github.com/JDis03/opencode-openai-codex-auth
23
+ */
24
+ import type { Plugin } from "@opencode-ai/plugin";
25
+ /**
26
+ * OpenAI Codex OAuth authentication plugin for opencode
27
+ *
28
+ * This plugin enables opencode to use OpenAI's Codex backend via ChatGPT Plus/Pro
29
+ * OAuth authentication, allowing users to leverage their ChatGPT subscription
30
+ * instead of OpenAI Platform API credits.
31
+ *
32
+ * @example
33
+ * ```json
34
+ * {
35
+ * "plugin": ["opencode-openai-codex-auth"],
36
+ * "model": "openai/gpt-5-codex"
37
+ * }
38
+ * ```
39
+ */
40
+ export declare const OpenAIAuthPlugin: Plugin;
41
+ export default OpenAIAuthPlugin;
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAsC/D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,EAAE,MA+N9B,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,226 @@
1
+ /**
2
+ * OpenAI ChatGPT (Codex) OAuth Authentication Plugin for opencode
3
+ *
4
+ * COMPLIANCE NOTICE:
5
+ * This plugin uses OpenAI's official OAuth authentication flow (the same method
6
+ * used by OpenAI's official Codex CLI at https://github.com/openai/codex).
7
+ *
8
+ * INTENDED USE: Personal development and coding assistance with your own
9
+ * ChatGPT Plus/Pro subscription.
10
+ *
11
+ * NOT INTENDED FOR: Commercial resale, multi-user services, high-volume
12
+ * automated extraction, or any use that violates OpenAI's Terms of Service.
13
+ *
14
+ * Users are responsible for ensuring their usage complies with:
15
+ * - OpenAI Terms of Use: https://openai.com/policies/terms-of-use/
16
+ * - OpenAI Usage Policies: https://openai.com/policies/usage-policies/
17
+ *
18
+ * For production applications, use the OpenAI Platform API: https://platform.openai.com/
19
+ *
20
+ * @license MIT with Usage Disclaimer (see LICENSE file)
21
+ * @author numman-ali
22
+ * @repository https://github.com/JDis03/opencode-openai-codex-auth
23
+ */
24
+ import { createAuthorizationFlow, decodeJWT, exchangeAuthorizationCode, parseAuthorizationInput, REDIRECT_URI, } from "./lib/auth/auth.js";
25
+ import { openBrowserUrl } from "./lib/auth/browser.js";
26
+ import { startLocalOAuthServer } from "./lib/auth/server.js";
27
+ import { getCodexMode, loadPluginConfig } from "./lib/config.js";
28
+ import { configureModelRegistrySource } from "./lib/request/helpers/model-registry.js";
29
+ import { AUTH_LABELS, CODEX_BASE_URL, DUMMY_API_KEY, ERROR_MESSAGES, JWT_CLAIM_PATH, LOG_STAGES, PLUGIN_NAME, PROVIDER_ID, } from "./lib/constants.js";
30
+ import { logRequest, logDebug } from "./lib/logger.js";
31
+ import { createCodexHeaders, extractRequestUrl, handleErrorResponse, handleSuccessResponse, refreshAndUpdateToken, rewriteUrlForCodex, shouldRefreshToken, transformRequestForCodex, } from "./lib/request/fetch-helpers.js";
32
+ /**
33
+ * OpenAI Codex OAuth authentication plugin for opencode
34
+ *
35
+ * This plugin enables opencode to use OpenAI's Codex backend via ChatGPT Plus/Pro
36
+ * OAuth authentication, allowing users to leverage their ChatGPT subscription
37
+ * instead of OpenAI Platform API credits.
38
+ *
39
+ * @example
40
+ * ```json
41
+ * {
42
+ * "plugin": ["opencode-openai-codex-auth"],
43
+ * "model": "openai/gpt-5-codex"
44
+ * }
45
+ * ```
46
+ */
47
+ export const OpenAIAuthPlugin = async ({ client }) => {
48
+ const buildManualOAuthFlow = (pkce, url) => ({
49
+ url,
50
+ method: "code",
51
+ instructions: AUTH_LABELS.INSTRUCTIONS_MANUAL,
52
+ callback: async (input) => {
53
+ const parsed = parseAuthorizationInput(input);
54
+ if (!parsed.code) {
55
+ return { type: "failed" };
56
+ }
57
+ const tokens = await exchangeAuthorizationCode(parsed.code, pkce.verifier, REDIRECT_URI);
58
+ return tokens?.type === "success" ? tokens : { type: "failed" };
59
+ },
60
+ });
61
+ return {
62
+ auth: {
63
+ provider: PROVIDER_ID,
64
+ /**
65
+ * Loader function that configures OAuth authentication and request handling
66
+ *
67
+ * This function:
68
+ * 1. Validates OAuth authentication
69
+ * 2. Extracts ChatGPT account ID from access token
70
+ * 3. Loads user configuration from opencode.json
71
+ * 4. Fetches Codex system instructions from GitHub (cached)
72
+ * 5. Returns SDK configuration with custom fetch implementation
73
+ *
74
+ * @param getAuth - Function to retrieve current auth state
75
+ * @param provider - Provider configuration from opencode.json
76
+ * @returns SDK configuration object or empty object for non-OAuth auth
77
+ */
78
+ async loader(getAuth, provider) {
79
+ const auth = await getAuth();
80
+ // Only handle OAuth auth type, skip API key auth
81
+ if (auth.type !== "oauth") {
82
+ return {};
83
+ }
84
+ // Extract ChatGPT account ID from JWT access token
85
+ const decoded = decodeJWT(auth.access);
86
+ const accountId = decoded?.[JWT_CLAIM_PATH]?.chatgpt_account_id;
87
+ if (!accountId) {
88
+ logDebug(`[${PLUGIN_NAME}] ${ERROR_MESSAGES.NO_ACCOUNT_ID} (skipping plugin)`);
89
+ return {};
90
+ }
91
+ // Extract user configuration (global + per-model options)
92
+ const providerConfig = provider;
93
+ const userConfig = {
94
+ global: providerConfig?.options || {},
95
+ models: providerConfig?.models || {},
96
+ };
97
+ // Load plugin configuration and determine CODEX_MODE
98
+ // Priority: CODEX_MODE env var > config file > default (true)
99
+ const pluginConfig = loadPluginConfig();
100
+ const codexMode = getCodexMode(pluginConfig);
101
+ // Opt-in: if a remote model registry overlay URL is configured,
102
+ // enable periodic background refresh (never blocks a request).
103
+ configureModelRegistrySource(pluginConfig.modelRegistryUrl);
104
+ // Return SDK configuration
105
+ return {
106
+ apiKey: DUMMY_API_KEY,
107
+ baseURL: CODEX_BASE_URL,
108
+ /**
109
+ * Custom fetch implementation for Codex API
110
+ *
111
+ * Handles:
112
+ * - Token refresh when expired
113
+ * - URL rewriting for Codex backend
114
+ * - Request body transformation
115
+ * - OAuth header injection
116
+ * - SSE to JSON conversion for non-tool requests
117
+ * - Error handling and logging
118
+ *
119
+ * @param input - Request URL or Request object
120
+ * @param init - Request options
121
+ * @returns Response from Codex API
122
+ */
123
+ async fetch(input, init) {
124
+ // Step 1: Check and refresh token if needed
125
+ let currentAuth = await getAuth();
126
+ if (shouldRefreshToken(currentAuth)) {
127
+ currentAuth = await refreshAndUpdateToken(currentAuth, client);
128
+ }
129
+ // Step 2: Extract and rewrite URL for Codex backend
130
+ const originalUrl = extractRequestUrl(input);
131
+ const url = rewriteUrlForCodex(originalUrl);
132
+ // Step 3: Transform request body with model-specific Codex instructions
133
+ // Instructions are fetched per model family (codex-max, codex, gpt-5.1)
134
+ // Capture original stream value before transformation
135
+ // generateText() sends no stream field, streamText() sends stream=true
136
+ const originalBody = init?.body ? JSON.parse(init.body) : {};
137
+ const isStreaming = originalBody.stream === true;
138
+ const transformation = await transformRequestForCodex(init, url, userConfig, codexMode);
139
+ const requestInit = transformation?.updatedInit ?? init;
140
+ // Step 4: Create headers with OAuth and ChatGPT account info
141
+ const accessToken = currentAuth.type === "oauth" ? currentAuth.access : "";
142
+ const headers = createCodexHeaders(requestInit, accountId, accessToken, {
143
+ model: transformation?.body.model,
144
+ promptCacheKey: transformation?.body?.prompt_cache_key,
145
+ });
146
+ // Step 5: Make request to Codex API
147
+ const response = await fetch(url, {
148
+ ...requestInit,
149
+ headers,
150
+ });
151
+ // Step 6: Log response
152
+ logRequest(LOG_STAGES.RESPONSE, {
153
+ status: response.status,
154
+ ok: response.ok,
155
+ statusText: response.statusText,
156
+ headers: Object.fromEntries(response.headers.entries()),
157
+ });
158
+ // Step 7: Handle error or success response
159
+ if (!response.ok) {
160
+ return await handleErrorResponse(response);
161
+ }
162
+ return await handleSuccessResponse(response, isStreaming);
163
+ },
164
+ };
165
+ },
166
+ methods: [
167
+ {
168
+ label: AUTH_LABELS.OAUTH,
169
+ type: "oauth",
170
+ /**
171
+ * OAuth authorization flow
172
+ *
173
+ * Steps:
174
+ * 1. Generate PKCE challenge and state for security
175
+ * 2. Start local OAuth callback server on port 1455
176
+ * 3. Open browser to OpenAI authorization page
177
+ * 4. Wait for user to complete login
178
+ * 5. Exchange authorization code for tokens
179
+ *
180
+ * @returns Authorization flow configuration
181
+ */
182
+ authorize: async () => {
183
+ const { pkce, state, url } = await createAuthorizationFlow();
184
+ const serverInfo = await startLocalOAuthServer({ state });
185
+ // Attempt to open browser automatically
186
+ openBrowserUrl(url);
187
+ if (!serverInfo.ready) {
188
+ serverInfo.close();
189
+ return buildManualOAuthFlow(pkce, url);
190
+ }
191
+ return {
192
+ url,
193
+ method: "auto",
194
+ instructions: AUTH_LABELS.INSTRUCTIONS,
195
+ callback: async () => {
196
+ const result = await serverInfo.waitForCode(state);
197
+ serverInfo.close();
198
+ if (!result) {
199
+ return { type: "failed" };
200
+ }
201
+ const tokens = await exchangeAuthorizationCode(result.code, pkce.verifier, REDIRECT_URI);
202
+ return tokens?.type === "success"
203
+ ? tokens
204
+ : { type: "failed" };
205
+ },
206
+ };
207
+ },
208
+ },
209
+ {
210
+ label: AUTH_LABELS.OAUTH_MANUAL,
211
+ type: "oauth",
212
+ authorize: async () => {
213
+ const { pkce, url } = await createAuthorizationFlow();
214
+ return buildManualOAuthFlow(pkce, url);
215
+ },
216
+ },
217
+ {
218
+ label: AUTH_LABELS.API_KEY,
219
+ type: "api",
220
+ },
221
+ ],
222
+ },
223
+ };
224
+ };
225
+ export default OpenAIAuthPlugin;
226
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { AuthorizationFlow, TokenResult, ParsedAuthInput, JWTPayload } from "../types.js";
2
+ export declare const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
3
+ export declare const AUTHORIZE_URL = "https://auth.openai.com/oauth/authorize";
4
+ export declare const TOKEN_URL = "https://auth.openai.com/oauth/token";
5
+ export declare const REDIRECT_URI = "http://localhost:1455/auth/callback";
6
+ export declare const SCOPE = "openid profile email offline_access";
7
+ /**
8
+ * Generate a random state value for OAuth flow
9
+ * @returns Random hex string
10
+ */
11
+ export declare function createState(): string;
12
+ /**
13
+ * Parse authorization code and state from user input
14
+ * @param input - User input (URL, code#state, or just code)
15
+ * @returns Parsed authorization data
16
+ */
17
+ export declare function parseAuthorizationInput(input: string): ParsedAuthInput;
18
+ /**
19
+ * Exchange authorization code for access and refresh tokens
20
+ * @param code - Authorization code from OAuth flow
21
+ * @param verifier - PKCE verifier
22
+ * @param redirectUri - OAuth redirect URI
23
+ * @returns Token result
24
+ */
25
+ export declare function exchangeAuthorizationCode(code: string, verifier: string, redirectUri?: string): Promise<TokenResult>;
26
+ /**
27
+ * Decode a JWT token to extract payload
28
+ * @param token - JWT token to decode
29
+ * @returns Decoded payload or null if invalid
30
+ */
31
+ export declare function decodeJWT(token: string): JWTPayload | null;
32
+ /**
33
+ * Refresh access token using refresh token
34
+ * @param refreshToken - Refresh token
35
+ * @returns Token result
36
+ */
37
+ export declare function refreshAccessToken(refreshToken: string): Promise<TokenResult>;
38
+ /**
39
+ * Create OAuth authorization flow
40
+ * @returns Authorization flow details
41
+ */
42
+ export declare function createAuthorizationFlow(): Promise<AuthorizationFlow>;
43
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../lib/auth/auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAY,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzG,eAAO,MAAM,SAAS,iCAAiC,CAAC;AACxD,eAAO,MAAM,aAAa,4CAA4C,CAAC;AACvE,eAAO,MAAM,SAAS,wCAAwC,CAAC;AAC/D,eAAO,MAAM,YAAY,wCAAwC,CAAC;AAClE,eAAO,MAAM,KAAK,wCAAwC,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAwBtE;AAED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC9C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,WAAW,GAAE,MAAqB,GAChC,OAAO,CAAC,WAAW,CAAC,CAoCtB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAU1D;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAkDnF;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAiB1E"}