oc-chatgpt-multi-auth 5.3.0 → 5.3.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.
package/README.md CHANGED
@@ -1,815 +1,815 @@
1
- # OpenAI Codex Auth Plugin for OpenCode
2
-
3
- [![npm version](https://img.shields.io/npm/v/oc-chatgpt-multi-auth.svg)](https://www.npmjs.com/package/oc-chatgpt-multi-auth)
4
- [![npm downloads](https://img.shields.io/npm/dw/oc-chatgpt-multi-auth.svg)](https://www.npmjs.com/package/oc-chatgpt-multi-auth)
5
-
6
- OAuth plugin for OpenCode that lets you use ChatGPT Plus/Pro rate limits with models like `gpt-5.2`, `gpt-5-codex`, and `gpt-5.1-codex-max` (plus optional entitlement-gated Spark IDs and legacy Codex aliases).
7
-
8
- > [!NOTE]
9
- > **Renamed from `opencode-openai-codex-auth-multi`** — If you were using the old package, update your config to use `oc-chatgpt-multi-auth` instead. The rename was necessary because OpenCode blocks plugins containing `opencode-openai-codex-auth` in the name.
10
-
11
- ## What You Get
12
-
13
- - **GPT-5.2, GPT-5 Codex, GPT-5.1 Codex Max** and all GPT-5.x variants via ChatGPT OAuth
14
- - **Multi-account support** — Add up to 20 ChatGPT accounts, health-aware rotation with automatic failover
15
- - **Per-project accounts** — Each project gets its own account storage (new in v4.10.0)
16
- - **Workspace-aware identity persistence** — Keeps workspace/org identity stable across token refresh and verify-flagged restore flows
17
- - **Click-to-switch** — Switch accounts directly from the OpenCode TUI
18
- - **Strict tool validation** — Automatically cleans schemas for compatibility with strict models
19
- - **Auto-update notifications** — Get notified when a new version is available
20
- - **21 template model presets** — Full variant system with reasoning levels (none/low/medium/high/xhigh)
21
- - **Prompt caching** — Session-based caching for faster multi-turn conversations
22
- - **Usage-aware errors** — Friendly messages with rate limit reset timing
23
- - **Plugin compatible** — Works alongside other OpenCode plugins (oh-my-opencode, dcp, etc.)
24
-
25
- ---
26
-
27
- <details open>
28
- <summary><b>Terms of Service Warning — Read Before Installing</b></summary>
29
-
30
- > [!CAUTION]
31
- > This plugin uses OpenAI's official OAuth authentication (the same method as OpenAI's official Codex CLI) for personal development use with your ChatGPT Plus/Pro subscription.
32
- >
33
- > **This plugin is for personal development only:**
34
- > - Not for commercial services, API resale, or multi-user applications
35
- > - For production use, see [OpenAI Platform API](https://platform.openai.com/)
36
- >
37
- > **By using this plugin, you acknowledge:**
38
- > - This is an unofficial tool not endorsed by OpenAI
39
- > - Users are responsible for compliance with [OpenAI's Terms of Use](https://openai.com/policies/terms-of-use/)
40
- > - You assume all risks associated with using this plugin
41
-
42
- </details>
43
-
44
- ---
45
-
46
- ## Installation
47
-
48
- <details open>
49
- <summary><b>For Humans</b></summary>
50
-
51
- **Option A: Let an LLM do it**
52
-
53
- Paste this into any LLM agent (Claude Code, OpenCode, Cursor, etc.):
54
-
55
- ```
56
- Install the oc-chatgpt-multi-auth plugin and add the OpenAI model definitions to ~/.config/opencode/opencode.json by following: https://raw.githubusercontent.com/ndycode/oc-chatgpt-multi-auth/main/README.md
57
- ```
58
-
59
- **Option B: One-command install**
60
-
61
- ```bash
62
- npx -y oc-chatgpt-multi-auth@latest
63
- ```
64
-
65
- This writes the config to `~/.config/opencode/opencode.json`, backs up existing config, and clears the plugin cache.
66
-
67
- > Want legacy config (OpenCode v1.0.209 and below)? Add `--legacy` flag.
68
-
69
- **Option C: Manual setup**
70
-
71
- 1. **Add the plugin** to `~/.config/opencode/opencode.json`:
72
-
73
- ```json
74
- {
75
- "plugin": ["oc-chatgpt-multi-auth@latest"]
76
- }
77
- ```
78
-
79
- 2. **Login** with your ChatGPT account:
80
-
81
- ```bash
82
- opencode auth login
83
- ```
84
-
85
- 3. **Add models** — Copy the [full configuration](#models) below
86
-
87
- 4. **Use it:**
88
-
89
- ```bash
90
- opencode run "Hello" --model=openai/gpt-5.2 --variant=medium
91
- ```
92
-
93
- </details>
94
-
95
- <details>
96
- <summary><b>For LLM Agents</b></summary>
97
-
98
- ### Step-by-Step Instructions
99
-
100
- 1. Edit the OpenCode configuration file at `~/.config/opencode/opencode.json`
101
-
102
- > **Note**: This path works on all platforms. On Windows, `~` resolves to your user home directory (e.g., `C:\Users\YourName`).
103
-
104
- 2. Add the plugin to the `plugin` array:
105
- ```json
106
- {
107
- "plugin": ["oc-chatgpt-multi-auth@latest"]
108
- }
109
- ```
110
-
111
- 3. Add the model definitions from the [Full Models Configuration](#full-models-configuration-copy-paste-ready) section
112
-
113
- 4. Set `provider` to `"openai"` and choose a model
114
-
115
- ### Verification
116
-
117
- ```bash
118
- opencode run "Hello" --model=openai/gpt-5.2 --variant=medium
119
- ```
120
-
121
- </details>
122
-
123
- ---
124
-
125
- ## Models
126
-
127
- ### Model Reference
128
-
129
- | Model | Variants | Notes |
130
- |-------|----------|-------|
131
- | `gpt-5.2` | none, low, medium, high, xhigh | Latest GPT-5.2 with reasoning levels |
132
- | `gpt-5-codex` | low, medium, high | Canonical Codex model for code generation (default: high) |
133
- | `gpt-5.3-codex-spark` | low, medium, high, xhigh | Spark IDs are supported by the plugin, but access is entitlement-gated by account/workspace |
134
- | `gpt-5.1-codex-max` | low, medium, high, xhigh | Maximum context Codex |
135
- | `gpt-5.1-codex` | low, medium, high | Standard Codex |
136
- | `gpt-5.1-codex-mini` | medium, high | Lightweight Codex |
137
- | `gpt-5.1` | none, low, medium, high | GPT-5.1 base model |
138
-
139
- Config templates intentionally omit Spark model IDs by default to reduce entitlement failures on unsupported accounts. Add Spark manually only if your workspace is entitled.
140
-
141
- **Using variants:**
142
- ```bash
143
- # Modern OpenCode (v1.0.210+)
144
- opencode run "Hello" --model=openai/gpt-5.2 --variant=high
145
-
146
- # Legacy OpenCode (v1.0.209 and below)
147
- opencode run "Hello" --model=openai/gpt-5.2-high
148
- ```
149
-
150
- <details>
151
- <summary><b>Full Models Configuration (Copy-Paste Ready)</b></summary>
152
-
153
- Add this to your `~/.config/opencode/opencode.json`:
154
-
155
- ```json
156
- {
157
- "$schema": "https://opencode.ai/config.json",
158
- "plugin": ["oc-chatgpt-multi-auth@latest"],
159
- "provider": {
160
- "openai": {
161
- "options": {
162
- "reasoningEffort": "medium",
163
- "reasoningSummary": "auto",
164
- "textVerbosity": "medium",
165
- "include": ["reasoning.encrypted_content"],
166
- "store": false
167
- },
168
- "models": {
169
- "gpt-5.2": {
170
- "name": "GPT 5.2 (OAuth)",
171
- "limit": { "context": 272000, "output": 128000 },
172
- "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
173
- "variants": {
174
- "none": { "reasoningEffort": "none" },
175
- "low": { "reasoningEffort": "low" },
176
- "medium": { "reasoningEffort": "medium" },
177
- "high": { "reasoningEffort": "high" },
178
- "xhigh": { "reasoningEffort": "xhigh" }
179
- }
180
- },
181
- "gpt-5-codex": {
182
- "name": "GPT 5 Codex (OAuth)",
183
- "limit": { "context": 272000, "output": 128000 },
184
- "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
185
- "variants": {
186
- "low": { "reasoningEffort": "low" },
187
- "medium": { "reasoningEffort": "medium" },
188
- "high": { "reasoningEffort": "high" }
189
- },
190
- "options": {
191
- "reasoningEffort": "high",
192
- "reasoningSummary": "detailed"
193
- }
194
- },
195
- "gpt-5.1-codex-max": {
196
- "name": "GPT 5.1 Codex Max (OAuth)",
197
- "limit": { "context": 272000, "output": 128000 },
198
- "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
199
- "variants": {
200
- "low": { "reasoningEffort": "low" },
201
- "medium": { "reasoningEffort": "medium" },
202
- "high": { "reasoningEffort": "high" },
203
- "xhigh": { "reasoningEffort": "xhigh" }
204
- }
205
- },
206
- "gpt-5.1-codex": {
207
- "name": "GPT 5.1 Codex (OAuth)",
208
- "limit": { "context": 272000, "output": 128000 },
209
- "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
210
- "variants": {
211
- "low": { "reasoningEffort": "low" },
212
- "medium": { "reasoningEffort": "medium" },
213
- "high": { "reasoningEffort": "high" }
214
- }
215
- },
216
- "gpt-5.1-codex-mini": {
217
- "name": "GPT 5.1 Codex Mini (OAuth)",
218
- "limit": { "context": 272000, "output": 128000 },
219
- "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
220
- "variants": {
221
- "medium": { "reasoningEffort": "medium" },
222
- "high": { "reasoningEffort": "high" }
223
- }
224
- },
225
- "gpt-5.1": {
226
- "name": "GPT 5.1 (OAuth)",
227
- "limit": { "context": 272000, "output": 128000 },
228
- "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
229
- "variants": {
230
- "none": { "reasoningEffort": "none" },
231
- "low": { "reasoningEffort": "low" },
232
- "medium": { "reasoningEffort": "medium" },
233
- "high": { "reasoningEffort": "high" }
234
- }
235
- }
236
- }
237
- }
238
- }
239
- }
240
- ```
241
-
242
- Optional Spark model block (manual add only when entitled):
243
- ```json
244
- "gpt-5.3-codex-spark": {
245
- "name": "GPT 5.3 Codex Spark (OAuth)",
246
- "limit": { "context": 272000, "output": 128000 },
247
- "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
248
- "variants": {
249
- "low": { "reasoningEffort": "low" },
250
- "medium": { "reasoningEffort": "medium" },
251
- "high": { "reasoningEffort": "high" },
252
- "xhigh": { "reasoningEffort": "xhigh" }
253
- }
254
- }
255
- ```
256
-
257
- For legacy OpenCode (v1.0.209 and below), use `config/opencode-legacy.json` which has individual model entries like `gpt-5.2-low`, `gpt-5.2-medium`, etc.
258
-
259
- </details>
260
-
261
- ---
262
-
263
- ## Multi-Account Setup
264
-
265
- Add multiple ChatGPT accounts for higher combined quotas. The plugin uses **health-aware rotation** with automatic failover and supports up to 20 accounts.
266
-
267
- ```bash
268
- opencode auth login # Run again to add more accounts
269
- ```
270
-
271
- ---
272
-
273
- ## Account Management Tools
274
-
275
- The plugin provides built-in tools for managing your OpenAI accounts. These are available directly in OpenCode — just ask the agent or type the tool name.
276
-
277
- > **Note:** Tools were renamed from `openai-accounts-*` to `codex-*` in v4.12.0 for brevity.
278
-
279
- ### codex-list
280
-
281
- List all configured accounts with their status.
282
-
283
- ```
284
- codex-list
285
- ```
286
-
287
- **Output:**
288
- ```
289
- OpenAI Accounts (3 total):
290
-
291
- [1] user@gmail.com (active)
292
- [2] work@company.com
293
- [3] backup@email.com
294
-
295
- Use codex-switch to change active account.
296
- ```
297
-
298
- ---
299
-
300
- ### codex-switch
301
-
302
- Switch to a different account by index (1-based).
303
-
304
- ```
305
- codex-switch index=2
306
- ```
307
-
308
- **Output:**
309
- ```
310
- Switched to account [2] work@company.com
311
- ```
312
-
313
- ---
314
-
315
- ### codex-status
316
-
317
- Show detailed status including rate limits and health scores.
318
-
319
- ```
320
- codex-status
321
- ```
322
-
323
- **Output:**
324
- ```
325
- OpenAI Account Status:
326
-
327
- [1] user@gmail.com (active)
328
- Health: 100/100
329
- Rate Limit: 45/50 requests remaining
330
- Resets: 2m 30s
331
- Last Used: 5 minutes ago
332
-
333
- [2] work@company.com
334
- Health: 85/100
335
- Rate Limit: 12/50 requests remaining
336
- Resets: 8m 15s
337
- Last Used: 1 hour ago
338
- ```
339
-
340
- ---
341
-
342
- ### codex-metrics
343
-
344
- Show live runtime metrics (request counts, latency, errors, rotations) for the current plugin process.
345
-
346
- ```
347
- codex-metrics
348
- ```
349
-
350
- **Output:**
351
- ```
352
- Codex Plugin Metrics:
353
-
354
- Uptime: 12m
355
- Total upstream requests: 84
356
- Successful responses: 77
357
- Failed responses: 7
358
- Average successful latency: 842ms
359
- ```
360
-
361
- ---
362
-
363
- ### codex-health
364
-
365
- Check if all account tokens are still valid (read-only check).
366
-
367
- ```
368
- codex-health
369
- ```
370
-
371
- **Output:**
372
- ```
373
- Checking 3 account(s):
374
-
375
- ✓ [1] user@gmail.com: Healthy
376
- ✓ [2] work@company.com: Healthy
377
- ✗ [3] old@expired.com: Token expired
378
-
379
- Summary: 2 healthy, 1 unhealthy
380
- ```
381
-
382
- ---
383
-
384
- ### codex-refresh
385
-
386
- Refresh all OAuth tokens and save them to disk. Use this after long idle periods.
387
-
388
- ```
389
- codex-refresh
390
- ```
391
-
392
- **Output:**
393
- ```
394
- Refreshing 3 account(s):
395
-
396
- ✓ [1] user@gmail.com: Refreshed
397
- ✓ [2] work@company.com: Refreshed
398
- ✗ [3] old@expired.com: Failed - Token expired
399
-
400
- Summary: 2 refreshed, 1 failed
401
- ```
402
-
403
- **Difference from health check:** `codex-health` only validates tokens. `codex-refresh` actually refreshes them and saves new tokens to disk.
404
-
405
- ---
406
-
407
- ### codex-remove
408
-
409
- Remove an account by index. Useful for cleaning up expired accounts.
410
-
411
- ```
412
- codex-remove index=3
413
- ```
414
-
415
- **Output:**
416
- ```
417
- Removed: [3] old@expired.com
418
-
419
- Remaining accounts: 2
420
- ```
421
-
422
- ---
423
-
424
- ### codex-export
425
-
426
- Export all accounts to a portable JSON file. Useful for backup or migration.
427
-
428
- ```
429
- codex-export path="~/backup/accounts.json"
430
- ```
431
-
432
- **Output:**
433
- ```
434
- Exported 3 account(s) to ~/backup/accounts.json
435
- ```
436
-
437
- ---
438
-
439
- ### codex-import
440
-
441
- Import accounts from a JSON file (exported via `codex-export`). Merges with existing accounts.
442
-
443
- ```
444
- codex-import path="~/backup/accounts.json"
445
- ```
446
-
447
- **Output:**
448
- ```
449
- Imported 2 new account(s) (1 duplicate skipped)
450
-
451
- Total accounts: 4
452
- ```
453
-
454
- ---
455
-
456
- ### Quick Reference
457
-
458
- | Tool | What It Does | Example |
459
- |------|--------------|---------|
460
- | `codex-list` | List all accounts | "list my accounts" |
461
- | `codex-switch` | Switch active account | "switch to account 2" |
462
- | `codex-status` | Show rate limits & health | "show account status" |
463
- | `codex-metrics` | Show runtime metrics | "show plugin metrics" |
464
- | `codex-health` | Validate tokens (read-only) | "check account health" |
465
- | `codex-refresh` | Refresh & save tokens | "refresh my tokens" |
466
- | `codex-remove` | Remove an account | "remove account 3" |
467
- | `codex-export` | Export accounts to file | "export my accounts" |
468
- | `codex-import` | Import accounts from file | "import accounts from backup" |
469
-
470
- ---
471
-
472
- ## Rotation Behavior
473
-
474
- **How rotation works:**
475
- - Health scoring tracks success/failure per account
476
- - Token bucket prevents hitting rate limits
477
- - Hybrid selection prefers healthy accounts with available tokens
478
- - Always retries when all accounts are rate-limited (waits for reset with live countdown)
479
- - 20% jitter on retry delays to avoid thundering herd
480
- - Auto-removes accounts after 3 consecutive auth failures (new in v4.11.0)
481
-
482
- **Per-project accounts (v4.10.0+):**
483
-
484
- By default, each project gets its own account storage namespace. This means you can keep different active accounts per project without writing account files into your repo. Works from subdirectories too; the plugin walks up to find the project root (v4.11.0). Disable with `perProjectAccounts: false` in your config.
485
-
486
- **Storage locations:**
487
- - Per-project: `~/.opencode/projects/{project-key}/openai-codex-accounts.json`
488
- - Global (when per-project disabled): `~/.opencode/openai-codex-accounts.json`
489
-
490
- ---
491
-
492
- ## Troubleshooting
493
-
494
- > **Quick reset**: Most issues can be resolved by deleting `~/.opencode/auth/openai.json` and running `opencode auth login` again.
495
-
496
- ### Configuration Paths (All Platforms)
497
-
498
- OpenCode uses `~/.config/opencode/` on **all platforms** including Windows.
499
-
500
- | File | Path |
501
- |------|------|
502
- | Main config | `~/.config/opencode/opencode.json` |
503
- | Auth tokens | `~/.opencode/auth/openai.json` |
504
- | Multi-account (global) | `~/.opencode/openai-codex-accounts.json` |
505
- | Multi-account (per-project) | `~/.opencode/projects/{project-key}/openai-codex-accounts.json` |
506
- | Flagged accounts | `~/.opencode/openai-codex-flagged-accounts.json` |
507
- | Plugin config | `~/.opencode/openai-codex-auth-config.json` |
508
- | Debug logs | `~/.opencode/logs/codex-plugin/` |
509
-
510
- > **Windows users**: `~` resolves to your user home directory (e.g., `C:\Users\YourName`).
511
-
512
- ---
513
-
514
- <details>
515
- <summary><b>401 Unauthorized Error</b></summary>
516
-
517
- **Cause:** Token expired or not authenticated.
518
-
519
- **Solutions:**
520
- 1. Re-authenticate:
521
- ```bash
522
- opencode auth login
523
- ```
524
- 2. Check auth file exists:
525
- ```bash
526
- cat ~/.opencode/auth/openai.json
527
- ```
528
-
529
- </details>
530
-
531
- <details>
532
- <summary><b>Browser Doesn't Open for OAuth</b></summary>
533
-
534
- **Cause:** Port 1455 conflict or SSH/WSL environment.
535
-
536
- **Solutions:**
537
- 1. **Manual URL paste:**
538
- - Re-run `opencode auth login`
539
- - Select **"ChatGPT Plus/Pro (manual URL paste)"**
540
- - Paste the full redirect URL (including `#code=...`) after login
541
-
542
- 2. **Check port availability:**
543
- ```bash
544
- # macOS/Linux
545
- lsof -i :1455
546
-
547
- # Windows
548
- netstat -ano | findstr :1455
549
- ```
550
-
551
- 3. **Stop Codex CLI if running** — Both use port 1455
552
-
553
- </details>
554
-
555
- <details>
556
- <summary><b>Model Not Found</b></summary>
557
-
558
- **Cause:** Missing provider prefix or config mismatch.
559
-
560
- **Solutions:**
561
- 1. Use `openai/` prefix:
562
- ```bash
563
- # Correct
564
- --model=openai/gpt-5.2
565
-
566
- # Wrong
567
- --model=gpt-5.2
568
- ```
569
-
570
- 2. Verify model is in your config:
571
- ```json
572
- { "models": { "gpt-5.2": { ... } } }
573
- ```
574
-
575
- </details>
576
-
577
- <details>
578
- <summary><b>Unsupported Codex Model for ChatGPT Account</b></summary>
579
-
580
- **Error example:** `Bad Request: {"detail":"The 'gpt-5.3-codex-spark' model is not supported when using Codex with a ChatGPT account."}`
581
-
582
- **Cause:** Active workspace/account is not entitled for the requested Codex model.
583
-
584
- **Solutions:**
585
- 1. Re-auth to refresh workspace selection (most common Spark fix):
586
- ```bash
587
- opencode auth login
588
- ```
589
- 2. Add another entitled account/workspace. The plugin will try remaining accounts/workspaces before model fallback.
590
- 3. Enable automatic fallback only if you want degraded-model retries when Spark is not entitled:
591
- ```bash
592
- CODEX_AUTH_UNSUPPORTED_MODEL_POLICY=fallback opencode
593
- ```
594
- 4. Use custom fallback chain in `~/.opencode/openai-codex-auth-config.json`:
595
- ```json
596
- {
597
- "unsupportedCodexPolicy": "fallback",
598
- "fallbackOnUnsupportedCodexModel": true,
599
- "unsupportedCodexFallbackChain": {
600
- "gpt-5-codex": ["gpt-5.2-codex"],
601
- "gpt-5.3-codex": ["gpt-5-codex", "gpt-5.2-codex"],
602
- "gpt-5.3-codex-spark": ["gpt-5-codex", "gpt-5.3-codex", "gpt-5.2-codex"]
603
- }
604
- }
605
- ```
606
- 5. Verify effective upstream model when needed:
607
- ```bash
608
- ENABLE_PLUGIN_REQUEST_LOGGING=1 CODEX_PLUGIN_LOG_BODIES=1 opencode run "ping" --model=openai/gpt-5.3-codex-spark
609
- ```
610
- The UI can keep showing your selected model while fallback is applied internally.
611
-
612
- </details>
613
-
614
- <details>
615
- <summary><b>Rate Limit Exceeded</b></summary>
616
-
617
- **Cause:** ChatGPT subscription usage limit reached.
618
-
619
- **Solutions:**
620
- 1. Wait for reset (plugin shows timing in error message)
621
- 2. Add more accounts: `opencode auth login`
622
- 3. Switch to a different model family
623
-
624
- </details>
625
-
626
- <details>
627
- <summary><b>Multi-Turn Context Lost</b></summary>
628
-
629
- **Cause:** Old plugin version or missing config.
630
-
631
- **Solutions:**
632
- 1. Update plugin:
633
- ```bash
634
- npx -y oc-chatgpt-multi-auth@latest
635
- ```
636
- 2. Ensure config has:
637
- ```json
638
- {
639
- "include": ["reasoning.encrypted_content"],
640
- "store": false
641
- }
642
- ```
643
-
644
- </details>
645
-
646
- <details>
647
- <summary><b>OAuth Callback Issues (Safari/WSL/Docker)</b></summary>
648
-
649
- **Safari HTTPS-only mode:**
650
- - Use Chrome or Firefox instead, or
651
- - Temporarily disable Safari > Settings > Privacy > "Enable HTTPS-only mode"
652
-
653
- **WSL2:**
654
- - Use VS Code's port forwarding, or
655
- - Configure Windows → WSL port forwarding
656
-
657
- **SSH / Remote:**
658
- ```bash
659
- ssh -L 1455:localhost:1455 user@remote
660
- ```
661
-
662
- **Docker / Containers:**
663
- - OAuth with localhost redirect doesn't work in containers
664
- - Use SSH port forwarding or manual URL flow
665
-
666
- </details>
667
-
668
- ---
669
-
670
- ## Plugin Compatibility
671
-
672
- ### oh-my-opencode
673
-
674
- Works alongside oh-my-opencode. No special configuration needed.
675
-
676
- ```json
677
- {
678
- "plugin": [
679
- "oc-chatgpt-multi-auth@latest",
680
- "oh-my-opencode@latest"
681
- ]
682
- }
683
- ```
684
-
685
- ### @tarquinen/opencode-dcp
686
-
687
- List this plugin before dcp:
688
-
689
- ```json
690
- {
691
- "plugin": [
692
- "oc-chatgpt-multi-auth@latest",
693
- "@tarquinen/opencode-dcp@latest"
694
- ]
695
- }
696
- ```
697
-
698
- ### Plugins You Don't Need
699
-
700
- - **openai-codex-auth** — Not needed. This plugin replaces the original.
701
-
702
- ---
703
-
704
- ## Configuration
705
-
706
- Create `~/.opencode/openai-codex-auth-config.json` for optional settings:
707
-
708
- ### Model Behavior
709
-
710
- | Option | Default | What It Does |
711
- |--------|---------|--------------|
712
- | `requestTransformMode` | `native` | Request shaping mode: `native` keeps OpenCode payloads unchanged; `legacy` enables Codex compatibility rewrites |
713
- | `codexMode` | `true` | Legacy-only bridge prompt behavior (applies when `requestTransformMode=legacy`) |
714
- | `codexTuiV2` | `true` | Enables Codex-style terminal UI output (set `false` for legacy output) |
715
- | `codexTuiColorProfile` | `truecolor` | Terminal color profile for Codex UI (`truecolor`, `ansi256`, `ansi16`) |
716
- | `codexTuiGlyphMode` | `ascii` | Glyph mode for Codex UI (`ascii`, `unicode`, `auto`) |
717
- | `fastSession` | `false` | Forces low-latency settings per request (`reasoningEffort=none/low`, `reasoningSummary=auto`, `textVerbosity=low`) |
718
- | `fastSessionStrategy` | `hybrid` | `hybrid` speeds simple turns but keeps full-depth on complex prompts; `always` forces fast tuning on every turn |
719
- | `fastSessionMaxInputItems` | `30` | Max input items kept when fast tuning is applied |
720
-
721
- ### Account Settings (v4.10.0+)
722
-
723
- | Option | Default | What It Does |
724
- |--------|---------|--------------|
725
- | `perProjectAccounts` | `true` | Each project gets its own account storage namespace under `~/.opencode/projects/` |
726
- | `toastDurationMs` | `5000` | How long toast notifications stay visible (ms) |
727
-
728
- ### Retry Behavior
729
-
730
- | Option | Default | What It Does |
731
- |--------|---------|--------------|
732
- | `retryAllAccountsRateLimited` | `true` | Wait and retry when all accounts are rate-limited |
733
- | `retryAllAccountsMaxWaitMs` | `0` | Max wait time (0 = unlimited) |
734
- | `retryAllAccountsMaxRetries` | `Infinity` | Max retry attempts |
735
- | `unsupportedCodexPolicy` | `strict` | Unsupported-model behavior: `strict` (return entitlement error) or `fallback` (retry next model in fallback chain) |
736
- | `fallbackOnUnsupportedCodexModel` | `false` | Legacy fallback toggle mapped to `unsupportedCodexPolicy` (prefer using `unsupportedCodexPolicy`) |
737
- | `fallbackToGpt52OnUnsupportedGpt53` | `true` | Legacy compatibility toggle for the `gpt-5.3-codex -> gpt-5.2-codex` edge when generic fallback is enabled |
738
- | `unsupportedCodexFallbackChain` | `{}` | Optional per-model fallback-chain override (map of `model -> [fallback1, fallback2, ...]`) |
739
- | `fetchTimeoutMs` | `60000` | Request timeout to Codex backend (ms) |
740
- | `streamStallTimeoutMs` | `45000` | Abort non-stream parsing if SSE stalls (ms) |
741
-
742
- Default unsupported-model fallback chain (used when `unsupportedCodexPolicy` is `fallback`):
743
- - `gpt-5.3-codex -> gpt-5-codex -> gpt-5.2-codex`
744
- - `gpt-5.3-codex-spark -> gpt-5-codex -> gpt-5.3-codex -> gpt-5.2-codex` (applies if you manually select Spark model IDs)
745
- - `gpt-5.2-codex -> gpt-5-codex`
746
- - `gpt-5.1-codex -> gpt-5-codex`
747
-
748
- ### Environment Variables
749
-
750
- ```bash
751
- DEBUG_CODEX_PLUGIN=1 opencode # Enable debug logging
752
- ENABLE_PLUGIN_REQUEST_LOGGING=1 opencode # Log request metadata
753
- CODEX_PLUGIN_LOG_BODIES=1 opencode # Include raw request/response payloads in request logs (sensitive)
754
- CODEX_PLUGIN_LOG_LEVEL=debug opencode # Set log level (debug|info|warn|error)
755
- CODEX_AUTH_REQUEST_TRANSFORM_MODE=legacy opencode # Re-enable legacy Codex request rewrites
756
- CODEX_MODE=0 opencode # Temporarily disable bridge prompt
757
- CODEX_TUI_V2=0 opencode # Disable Codex-style UI (legacy output)
758
- CODEX_TUI_COLOR_PROFILE=ansi16 opencode # Force UI color profile
759
- CODEX_TUI_GLYPHS=unicode opencode # Override glyph mode (ascii|unicode|auto)
760
- CODEX_AUTH_PREWARM=0 opencode # Disable startup prewarm (prompt/instruction cache warmup)
761
- CODEX_AUTH_FAST_SESSION=1 opencode # Enable faster response defaults
762
- CODEX_AUTH_FAST_SESSION_STRATEGY=always opencode # Force fast mode for all prompts
763
- CODEX_AUTH_FAST_SESSION_MAX_INPUT_ITEMS=24 opencode # Tune fast-mode history window
764
- CODEX_AUTH_UNSUPPORTED_MODEL_POLICY=fallback opencode # Enable generic unsupported-model fallback
765
- CODEX_AUTH_FALLBACK_UNSUPPORTED_MODEL=1 opencode # Legacy fallback toggle (prefer policy var above)
766
- CODEX_AUTH_FALLBACK_GPT53_TO_GPT52=0 opencode # Disable only the legacy gpt-5.3 -> gpt-5.2 edge
767
- CODEX_AUTH_FETCH_TIMEOUT_MS=120000 opencode # Override request timeout
768
- CODEX_AUTH_STREAM_STALL_TIMEOUT_MS=60000 opencode # Override SSE stall timeout
769
- ```
770
-
771
- For all options, see [docs/configuration.md](docs/configuration.md).
772
-
773
- ---
774
-
775
- ## Documentation
776
-
777
- - [Getting Started](docs/getting-started.md) — Complete installation guide
778
- - [Configuration](docs/configuration.md) — All configuration options
779
- - [Troubleshooting](docs/troubleshooting.md) — Common issues and fixes
780
- - [Architecture](docs/development/ARCHITECTURE.md) — How the plugin works
781
-
782
- ---
783
-
784
- ## Credits
785
-
786
- - [numman-ali/opencode-openai-codex-auth](https://github.com/numman-ali/opencode-openai-codex-auth) by [numman-ali](https://github.com/numman-ali) — Original plugin
787
- - [ndycode](https://github.com/ndycode) — Multi-account support and maintenance
788
-
789
- ## License
790
-
791
- MIT License. See [LICENSE](LICENSE) for details.
792
-
793
- <details>
794
- <summary><b>Legal</b></summary>
795
-
796
- ### Intended Use
797
-
798
- - Personal / internal development only
799
- - Respect subscription quotas and data handling policies
800
- - Not for production services or bypassing intended limits
801
-
802
- ### Warning
803
-
804
- By using this plugin, you acknowledge:
805
-
806
- - **Terms of Service risk** — This approach may violate ToS of AI model providers
807
- - **No guarantees** — APIs may change without notice
808
- - **Assumption of risk** — You assume all legal, financial, and technical risks
809
-
810
- ### Disclaimer
811
-
812
- - Not affiliated with OpenAI. This is an independent open-source project.
813
- - "ChatGPT", "GPT-5", "Codex", and "OpenAI" are trademarks of OpenAI, L.L.C.
814
-
815
- </details>
1
+ # OpenAI Codex Auth Plugin for OpenCode
2
+
3
+ [![npm version](https://img.shields.io/npm/v/oc-chatgpt-multi-auth.svg)](https://www.npmjs.com/package/oc-chatgpt-multi-auth)
4
+ [![npm downloads](https://img.shields.io/npm/dw/oc-chatgpt-multi-auth.svg)](https://www.npmjs.com/package/oc-chatgpt-multi-auth)
5
+
6
+ OAuth plugin for OpenCode that lets you use ChatGPT Plus/Pro rate limits with models like `gpt-5.2`, `gpt-5-codex`, and `gpt-5.1-codex-max` (plus optional entitlement-gated Spark IDs and legacy Codex aliases).
7
+
8
+ > [!NOTE]
9
+ > **Renamed from `opencode-openai-codex-auth-multi`** — If you were using the old package, update your config to use `oc-chatgpt-multi-auth` instead. The rename was necessary because OpenCode blocks plugins containing `opencode-openai-codex-auth` in the name.
10
+
11
+ ## What You Get
12
+
13
+ - **GPT-5.2, GPT-5 Codex, GPT-5.1 Codex Max** and all GPT-5.x variants via ChatGPT OAuth
14
+ - **Multi-account support** — Add up to 20 ChatGPT accounts, health-aware rotation with automatic failover
15
+ - **Per-project accounts** — Each project gets its own account storage (new in v4.10.0)
16
+ - **Workspace-aware identity persistence** — Keeps workspace/org identity stable across token refresh and verify-flagged restore flows
17
+ - **Click-to-switch** — Switch accounts directly from the OpenCode TUI
18
+ - **Strict tool validation** — Automatically cleans schemas for compatibility with strict models
19
+ - **Auto-update notifications** — Get notified when a new version is available
20
+ - **21 template model presets** — Full variant system with reasoning levels (none/low/medium/high/xhigh)
21
+ - **Prompt caching** — Session-based caching for faster multi-turn conversations
22
+ - **Usage-aware errors** — Friendly messages with rate limit reset timing
23
+ - **Plugin compatible** — Works alongside other OpenCode plugins (oh-my-opencode, dcp, etc.)
24
+
25
+ ---
26
+
27
+ <details open>
28
+ <summary><b>Terms of Service Warning — Read Before Installing</b></summary>
29
+
30
+ > [!CAUTION]
31
+ > This plugin uses OpenAI's official OAuth authentication (the same method as OpenAI's official Codex CLI) for personal development use with your ChatGPT Plus/Pro subscription.
32
+ >
33
+ > **This plugin is for personal development only:**
34
+ > - Not for commercial services, API resale, or multi-user applications
35
+ > - For production use, see [OpenAI Platform API](https://platform.openai.com/)
36
+ >
37
+ > **By using this plugin, you acknowledge:**
38
+ > - This is an unofficial tool not endorsed by OpenAI
39
+ > - Users are responsible for compliance with [OpenAI's Terms of Use](https://openai.com/policies/terms-of-use/)
40
+ > - You assume all risks associated with using this plugin
41
+
42
+ </details>
43
+
44
+ ---
45
+
46
+ ## Installation
47
+
48
+ <details open>
49
+ <summary><b>For Humans</b></summary>
50
+
51
+ **Option A: Let an LLM do it**
52
+
53
+ Paste this into any LLM agent (Claude Code, OpenCode, Cursor, etc.):
54
+
55
+ ```
56
+ Install the oc-chatgpt-multi-auth plugin and add the OpenAI model definitions to ~/.config/opencode/opencode.json by following: https://raw.githubusercontent.com/ndycode/oc-chatgpt-multi-auth/main/README.md
57
+ ```
58
+
59
+ **Option B: One-command install**
60
+
61
+ ```bash
62
+ npx -y oc-chatgpt-multi-auth@latest
63
+ ```
64
+
65
+ This writes the config to `~/.config/opencode/opencode.json`, backs up existing config, and clears the plugin cache.
66
+
67
+ > Want legacy config (OpenCode v1.0.209 and below)? Add `--legacy` flag.
68
+
69
+ **Option C: Manual setup**
70
+
71
+ 1. **Add the plugin** to `~/.config/opencode/opencode.json`:
72
+
73
+ ```json
74
+ {
75
+ "plugin": ["oc-chatgpt-multi-auth@latest"]
76
+ }
77
+ ```
78
+
79
+ 2. **Login** with your ChatGPT account:
80
+
81
+ ```bash
82
+ opencode auth login
83
+ ```
84
+
85
+ 3. **Add models** — Copy the [full configuration](#models) below
86
+
87
+ 4. **Use it:**
88
+
89
+ ```bash
90
+ opencode run "Hello" --model=openai/gpt-5.2 --variant=medium
91
+ ```
92
+
93
+ </details>
94
+
95
+ <details>
96
+ <summary><b>For LLM Agents</b></summary>
97
+
98
+ ### Step-by-Step Instructions
99
+
100
+ 1. Edit the OpenCode configuration file at `~/.config/opencode/opencode.json`
101
+
102
+ > **Note**: This path works on all platforms. On Windows, `~` resolves to your user home directory (e.g., `C:\Users\YourName`).
103
+
104
+ 2. Add the plugin to the `plugin` array:
105
+ ```json
106
+ {
107
+ "plugin": ["oc-chatgpt-multi-auth@latest"]
108
+ }
109
+ ```
110
+
111
+ 3. Add the model definitions from the [Full Models Configuration](#full-models-configuration-copy-paste-ready) section
112
+
113
+ 4. Set `provider` to `"openai"` and choose a model
114
+
115
+ ### Verification
116
+
117
+ ```bash
118
+ opencode run "Hello" --model=openai/gpt-5.2 --variant=medium
119
+ ```
120
+
121
+ </details>
122
+
123
+ ---
124
+
125
+ ## Models
126
+
127
+ ### Model Reference
128
+
129
+ | Model | Variants | Notes |
130
+ |-------|----------|-------|
131
+ | `gpt-5.2` | none, low, medium, high, xhigh | Latest GPT-5.2 with reasoning levels |
132
+ | `gpt-5-codex` | low, medium, high | Canonical Codex model for code generation (default: high) |
133
+ | `gpt-5.3-codex-spark` | low, medium, high, xhigh | Spark IDs are supported by the plugin, but access is entitlement-gated by account/workspace |
134
+ | `gpt-5.1-codex-max` | low, medium, high, xhigh | Maximum context Codex |
135
+ | `gpt-5.1-codex` | low, medium, high | Standard Codex |
136
+ | `gpt-5.1-codex-mini` | medium, high | Lightweight Codex |
137
+ | `gpt-5.1` | none, low, medium, high | GPT-5.1 base model |
138
+
139
+ Config templates intentionally omit Spark model IDs by default to reduce entitlement failures on unsupported accounts. Add Spark manually only if your workspace is entitled.
140
+
141
+ **Using variants:**
142
+ ```bash
143
+ # Modern OpenCode (v1.0.210+)
144
+ opencode run "Hello" --model=openai/gpt-5.2 --variant=high
145
+
146
+ # Legacy OpenCode (v1.0.209 and below)
147
+ opencode run "Hello" --model=openai/gpt-5.2-high
148
+ ```
149
+
150
+ <details>
151
+ <summary><b>Full Models Configuration (Copy-Paste Ready)</b></summary>
152
+
153
+ Add this to your `~/.config/opencode/opencode.json`:
154
+
155
+ ```json
156
+ {
157
+ "$schema": "https://opencode.ai/config.json",
158
+ "plugin": ["oc-chatgpt-multi-auth@latest"],
159
+ "provider": {
160
+ "openai": {
161
+ "options": {
162
+ "reasoningEffort": "medium",
163
+ "reasoningSummary": "auto",
164
+ "textVerbosity": "medium",
165
+ "include": ["reasoning.encrypted_content"],
166
+ "store": false
167
+ },
168
+ "models": {
169
+ "gpt-5.2": {
170
+ "name": "GPT 5.2 (OAuth)",
171
+ "limit": { "context": 272000, "output": 128000 },
172
+ "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
173
+ "variants": {
174
+ "none": { "reasoningEffort": "none" },
175
+ "low": { "reasoningEffort": "low" },
176
+ "medium": { "reasoningEffort": "medium" },
177
+ "high": { "reasoningEffort": "high" },
178
+ "xhigh": { "reasoningEffort": "xhigh" }
179
+ }
180
+ },
181
+ "gpt-5-codex": {
182
+ "name": "GPT 5 Codex (OAuth)",
183
+ "limit": { "context": 272000, "output": 128000 },
184
+ "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
185
+ "variants": {
186
+ "low": { "reasoningEffort": "low" },
187
+ "medium": { "reasoningEffort": "medium" },
188
+ "high": { "reasoningEffort": "high" }
189
+ },
190
+ "options": {
191
+ "reasoningEffort": "high",
192
+ "reasoningSummary": "detailed"
193
+ }
194
+ },
195
+ "gpt-5.1-codex-max": {
196
+ "name": "GPT 5.1 Codex Max (OAuth)",
197
+ "limit": { "context": 272000, "output": 128000 },
198
+ "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
199
+ "variants": {
200
+ "low": { "reasoningEffort": "low" },
201
+ "medium": { "reasoningEffort": "medium" },
202
+ "high": { "reasoningEffort": "high" },
203
+ "xhigh": { "reasoningEffort": "xhigh" }
204
+ }
205
+ },
206
+ "gpt-5.1-codex": {
207
+ "name": "GPT 5.1 Codex (OAuth)",
208
+ "limit": { "context": 272000, "output": 128000 },
209
+ "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
210
+ "variants": {
211
+ "low": { "reasoningEffort": "low" },
212
+ "medium": { "reasoningEffort": "medium" },
213
+ "high": { "reasoningEffort": "high" }
214
+ }
215
+ },
216
+ "gpt-5.1-codex-mini": {
217
+ "name": "GPT 5.1 Codex Mini (OAuth)",
218
+ "limit": { "context": 272000, "output": 128000 },
219
+ "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
220
+ "variants": {
221
+ "medium": { "reasoningEffort": "medium" },
222
+ "high": { "reasoningEffort": "high" }
223
+ }
224
+ },
225
+ "gpt-5.1": {
226
+ "name": "GPT 5.1 (OAuth)",
227
+ "limit": { "context": 272000, "output": 128000 },
228
+ "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
229
+ "variants": {
230
+ "none": { "reasoningEffort": "none" },
231
+ "low": { "reasoningEffort": "low" },
232
+ "medium": { "reasoningEffort": "medium" },
233
+ "high": { "reasoningEffort": "high" }
234
+ }
235
+ }
236
+ }
237
+ }
238
+ }
239
+ }
240
+ ```
241
+
242
+ Optional Spark model block (manual add only when entitled):
243
+ ```json
244
+ "gpt-5.3-codex-spark": {
245
+ "name": "GPT 5.3 Codex Spark (OAuth)",
246
+ "limit": { "context": 272000, "output": 128000 },
247
+ "modalities": { "input": ["text", "image", "pdf"], "output": ["text"] },
248
+ "variants": {
249
+ "low": { "reasoningEffort": "low" },
250
+ "medium": { "reasoningEffort": "medium" },
251
+ "high": { "reasoningEffort": "high" },
252
+ "xhigh": { "reasoningEffort": "xhigh" }
253
+ }
254
+ }
255
+ ```
256
+
257
+ For legacy OpenCode (v1.0.209 and below), use `config/opencode-legacy.json` which has individual model entries like `gpt-5.2-low`, `gpt-5.2-medium`, etc.
258
+
259
+ </details>
260
+
261
+ ---
262
+
263
+ ## Multi-Account Setup
264
+
265
+ Add multiple ChatGPT accounts for higher combined quotas. The plugin uses **health-aware rotation** with automatic failover and supports up to 20 accounts.
266
+
267
+ ```bash
268
+ opencode auth login # Run again to add more accounts
269
+ ```
270
+
271
+ ---
272
+
273
+ ## Account Management Tools
274
+
275
+ The plugin provides built-in tools for managing your OpenAI accounts. These are available directly in OpenCode — just ask the agent or type the tool name.
276
+
277
+ > **Note:** Tools were renamed from `openai-accounts-*` to `codex-*` in v4.12.0 for brevity.
278
+
279
+ ### codex-list
280
+
281
+ List all configured accounts with their status.
282
+
283
+ ```
284
+ codex-list
285
+ ```
286
+
287
+ **Output:**
288
+ ```
289
+ OpenAI Accounts (3 total):
290
+
291
+ [1] user@gmail.com (active)
292
+ [2] work@company.com
293
+ [3] backup@email.com
294
+
295
+ Use codex-switch to change active account.
296
+ ```
297
+
298
+ ---
299
+
300
+ ### codex-switch
301
+
302
+ Switch to a different account by index (1-based).
303
+
304
+ ```
305
+ codex-switch index=2
306
+ ```
307
+
308
+ **Output:**
309
+ ```
310
+ Switched to account [2] work@company.com
311
+ ```
312
+
313
+ ---
314
+
315
+ ### codex-status
316
+
317
+ Show detailed status including rate limits and health scores.
318
+
319
+ ```
320
+ codex-status
321
+ ```
322
+
323
+ **Output:**
324
+ ```
325
+ OpenAI Account Status:
326
+
327
+ [1] user@gmail.com (active)
328
+ Health: 100/100
329
+ Rate Limit: 45/50 requests remaining
330
+ Resets: 2m 30s
331
+ Last Used: 5 minutes ago
332
+
333
+ [2] work@company.com
334
+ Health: 85/100
335
+ Rate Limit: 12/50 requests remaining
336
+ Resets: 8m 15s
337
+ Last Used: 1 hour ago
338
+ ```
339
+
340
+ ---
341
+
342
+ ### codex-metrics
343
+
344
+ Show live runtime metrics (request counts, latency, errors, rotations) for the current plugin process.
345
+
346
+ ```
347
+ codex-metrics
348
+ ```
349
+
350
+ **Output:**
351
+ ```
352
+ Codex Plugin Metrics:
353
+
354
+ Uptime: 12m
355
+ Total upstream requests: 84
356
+ Successful responses: 77
357
+ Failed responses: 7
358
+ Average successful latency: 842ms
359
+ ```
360
+
361
+ ---
362
+
363
+ ### codex-health
364
+
365
+ Check if all account tokens are still valid (read-only check).
366
+
367
+ ```
368
+ codex-health
369
+ ```
370
+
371
+ **Output:**
372
+ ```
373
+ Checking 3 account(s):
374
+
375
+ ✓ [1] user@gmail.com: Healthy
376
+ ✓ [2] work@company.com: Healthy
377
+ ✗ [3] old@expired.com: Token expired
378
+
379
+ Summary: 2 healthy, 1 unhealthy
380
+ ```
381
+
382
+ ---
383
+
384
+ ### codex-refresh
385
+
386
+ Refresh all OAuth tokens and save them to disk. Use this after long idle periods.
387
+
388
+ ```
389
+ codex-refresh
390
+ ```
391
+
392
+ **Output:**
393
+ ```
394
+ Refreshing 3 account(s):
395
+
396
+ ✓ [1] user@gmail.com: Refreshed
397
+ ✓ [2] work@company.com: Refreshed
398
+ ✗ [3] old@expired.com: Failed - Token expired
399
+
400
+ Summary: 2 refreshed, 1 failed
401
+ ```
402
+
403
+ **Difference from health check:** `codex-health` only validates tokens. `codex-refresh` actually refreshes them and saves new tokens to disk.
404
+
405
+ ---
406
+
407
+ ### codex-remove
408
+
409
+ Remove an account by index. Useful for cleaning up expired accounts.
410
+
411
+ ```
412
+ codex-remove index=3
413
+ ```
414
+
415
+ **Output:**
416
+ ```
417
+ Removed: [3] old@expired.com
418
+
419
+ Remaining accounts: 2
420
+ ```
421
+
422
+ ---
423
+
424
+ ### codex-export
425
+
426
+ Export all accounts to a portable JSON file. Useful for backup or migration.
427
+
428
+ ```
429
+ codex-export path="~/backup/accounts.json"
430
+ ```
431
+
432
+ **Output:**
433
+ ```
434
+ Exported 3 account(s) to ~/backup/accounts.json
435
+ ```
436
+
437
+ ---
438
+
439
+ ### codex-import
440
+
441
+ Import accounts from a JSON file (exported via `codex-export`). Merges with existing accounts.
442
+
443
+ ```
444
+ codex-import path="~/backup/accounts.json"
445
+ ```
446
+
447
+ **Output:**
448
+ ```
449
+ Imported 2 new account(s) (1 duplicate skipped)
450
+
451
+ Total accounts: 4
452
+ ```
453
+
454
+ ---
455
+
456
+ ### Quick Reference
457
+
458
+ | Tool | What It Does | Example |
459
+ |------|--------------|---------|
460
+ | `codex-list` | List all accounts | "list my accounts" |
461
+ | `codex-switch` | Switch active account | "switch to account 2" |
462
+ | `codex-status` | Show rate limits & health | "show account status" |
463
+ | `codex-metrics` | Show runtime metrics | "show plugin metrics" |
464
+ | `codex-health` | Validate tokens (read-only) | "check account health" |
465
+ | `codex-refresh` | Refresh & save tokens | "refresh my tokens" |
466
+ | `codex-remove` | Remove an account | "remove account 3" |
467
+ | `codex-export` | Export accounts to file | "export my accounts" |
468
+ | `codex-import` | Import accounts from file | "import accounts from backup" |
469
+
470
+ ---
471
+
472
+ ## Rotation Behavior
473
+
474
+ **How rotation works:**
475
+ - Health scoring tracks success/failure per account
476
+ - Token bucket prevents hitting rate limits
477
+ - Hybrid selection prefers healthy accounts with available tokens
478
+ - Always retries when all accounts are rate-limited (waits for reset with live countdown)
479
+ - 20% jitter on retry delays to avoid thundering herd
480
+ - Auto-removes accounts after 3 consecutive auth failures (new in v4.11.0)
481
+
482
+ **Per-project accounts (v4.10.0+):**
483
+
484
+ By default, each project gets its own account storage namespace. This means you can keep different active accounts per project without writing account files into your repo. Works from subdirectories too; the plugin walks up to find the project root (v4.11.0). Disable with `perProjectAccounts: false` in your config.
485
+
486
+ **Storage locations:**
487
+ - Per-project: `~/.opencode/projects/{project-key}/openai-codex-accounts.json`
488
+ - Global (when per-project disabled): `~/.opencode/openai-codex-accounts.json`
489
+
490
+ ---
491
+
492
+ ## Troubleshooting
493
+
494
+ > **Quick reset**: Most issues can be resolved by deleting `~/.opencode/auth/openai.json` and running `opencode auth login` again.
495
+
496
+ ### Configuration Paths (All Platforms)
497
+
498
+ OpenCode uses `~/.config/opencode/` on **all platforms** including Windows.
499
+
500
+ | File | Path |
501
+ |------|------|
502
+ | Main config | `~/.config/opencode/opencode.json` |
503
+ | Auth tokens | `~/.opencode/auth/openai.json` |
504
+ | Multi-account (global) | `~/.opencode/openai-codex-accounts.json` |
505
+ | Multi-account (per-project) | `~/.opencode/projects/{project-key}/openai-codex-accounts.json` |
506
+ | Flagged accounts | `~/.opencode/openai-codex-flagged-accounts.json` |
507
+ | Plugin config | `~/.opencode/openai-codex-auth-config.json` |
508
+ | Debug logs | `~/.opencode/logs/codex-plugin/` |
509
+
510
+ > **Windows users**: `~` resolves to your user home directory (e.g., `C:\Users\YourName`).
511
+
512
+ ---
513
+
514
+ <details>
515
+ <summary><b>401 Unauthorized Error</b></summary>
516
+
517
+ **Cause:** Token expired or not authenticated.
518
+
519
+ **Solutions:**
520
+ 1. Re-authenticate:
521
+ ```bash
522
+ opencode auth login
523
+ ```
524
+ 2. Check auth file exists:
525
+ ```bash
526
+ cat ~/.opencode/auth/openai.json
527
+ ```
528
+
529
+ </details>
530
+
531
+ <details>
532
+ <summary><b>Browser Doesn't Open for OAuth</b></summary>
533
+
534
+ **Cause:** Port 1455 conflict or SSH/WSL environment.
535
+
536
+ **Solutions:**
537
+ 1. **Manual URL paste:**
538
+ - Re-run `opencode auth login`
539
+ - Select **"ChatGPT Plus/Pro (manual URL paste)"**
540
+ - Paste the full redirect URL (including `#code=...`) after login
541
+
542
+ 2. **Check port availability:**
543
+ ```bash
544
+ # macOS/Linux
545
+ lsof -i :1455
546
+
547
+ # Windows
548
+ netstat -ano | findstr :1455
549
+ ```
550
+
551
+ 3. **Stop Codex CLI if running** — Both use port 1455
552
+
553
+ </details>
554
+
555
+ <details>
556
+ <summary><b>Model Not Found</b></summary>
557
+
558
+ **Cause:** Missing provider prefix or config mismatch.
559
+
560
+ **Solutions:**
561
+ 1. Use `openai/` prefix:
562
+ ```bash
563
+ # Correct
564
+ --model=openai/gpt-5.2
565
+
566
+ # Wrong
567
+ --model=gpt-5.2
568
+ ```
569
+
570
+ 2. Verify model is in your config:
571
+ ```json
572
+ { "models": { "gpt-5.2": { ... } } }
573
+ ```
574
+
575
+ </details>
576
+
577
+ <details>
578
+ <summary><b>Unsupported Codex Model for ChatGPT Account</b></summary>
579
+
580
+ **Error example:** `Bad Request: {"detail":"The 'gpt-5.3-codex-spark' model is not supported when using Codex with a ChatGPT account."}`
581
+
582
+ **Cause:** Active workspace/account is not entitled for the requested Codex model.
583
+
584
+ **Solutions:**
585
+ 1. Re-auth to refresh workspace selection (most common Spark fix):
586
+ ```bash
587
+ opencode auth login
588
+ ```
589
+ 2. Add another entitled account/workspace. The plugin will try remaining accounts/workspaces before model fallback.
590
+ 3. Enable automatic fallback only if you want degraded-model retries when Spark is not entitled:
591
+ ```bash
592
+ CODEX_AUTH_UNSUPPORTED_MODEL_POLICY=fallback opencode
593
+ ```
594
+ 4. Use custom fallback chain in `~/.opencode/openai-codex-auth-config.json`:
595
+ ```json
596
+ {
597
+ "unsupportedCodexPolicy": "fallback",
598
+ "fallbackOnUnsupportedCodexModel": true,
599
+ "unsupportedCodexFallbackChain": {
600
+ "gpt-5-codex": ["gpt-5.2-codex"],
601
+ "gpt-5.3-codex": ["gpt-5-codex", "gpt-5.2-codex"],
602
+ "gpt-5.3-codex-spark": ["gpt-5-codex", "gpt-5.3-codex", "gpt-5.2-codex"]
603
+ }
604
+ }
605
+ ```
606
+ 5. Verify effective upstream model when needed:
607
+ ```bash
608
+ ENABLE_PLUGIN_REQUEST_LOGGING=1 CODEX_PLUGIN_LOG_BODIES=1 opencode run "ping" --model=openai/gpt-5.3-codex-spark
609
+ ```
610
+ The UI can keep showing your selected model while fallback is applied internally.
611
+
612
+ </details>
613
+
614
+ <details>
615
+ <summary><b>Rate Limit Exceeded</b></summary>
616
+
617
+ **Cause:** ChatGPT subscription usage limit reached.
618
+
619
+ **Solutions:**
620
+ 1. Wait for reset (plugin shows timing in error message)
621
+ 2. Add more accounts: `opencode auth login`
622
+ 3. Switch to a different model family
623
+
624
+ </details>
625
+
626
+ <details>
627
+ <summary><b>Multi-Turn Context Lost</b></summary>
628
+
629
+ **Cause:** Old plugin version or missing config.
630
+
631
+ **Solutions:**
632
+ 1. Update plugin:
633
+ ```bash
634
+ npx -y oc-chatgpt-multi-auth@latest
635
+ ```
636
+ 2. Ensure config has:
637
+ ```json
638
+ {
639
+ "include": ["reasoning.encrypted_content"],
640
+ "store": false
641
+ }
642
+ ```
643
+
644
+ </details>
645
+
646
+ <details>
647
+ <summary><b>OAuth Callback Issues (Safari/WSL/Docker)</b></summary>
648
+
649
+ **Safari HTTPS-only mode:**
650
+ - Use Chrome or Firefox instead, or
651
+ - Temporarily disable Safari > Settings > Privacy > "Enable HTTPS-only mode"
652
+
653
+ **WSL2:**
654
+ - Use VS Code's port forwarding, or
655
+ - Configure Windows → WSL port forwarding
656
+
657
+ **SSH / Remote:**
658
+ ```bash
659
+ ssh -L 1455:localhost:1455 user@remote
660
+ ```
661
+
662
+ **Docker / Containers:**
663
+ - OAuth with localhost redirect doesn't work in containers
664
+ - Use SSH port forwarding or manual URL flow
665
+
666
+ </details>
667
+
668
+ ---
669
+
670
+ ## Plugin Compatibility
671
+
672
+ ### oh-my-opencode
673
+
674
+ Works alongside oh-my-opencode. No special configuration needed.
675
+
676
+ ```json
677
+ {
678
+ "plugin": [
679
+ "oc-chatgpt-multi-auth@latest",
680
+ "oh-my-opencode@latest"
681
+ ]
682
+ }
683
+ ```
684
+
685
+ ### @tarquinen/opencode-dcp
686
+
687
+ List this plugin before dcp:
688
+
689
+ ```json
690
+ {
691
+ "plugin": [
692
+ "oc-chatgpt-multi-auth@latest",
693
+ "@tarquinen/opencode-dcp@latest"
694
+ ]
695
+ }
696
+ ```
697
+
698
+ ### Plugins You Don't Need
699
+
700
+ - **openai-codex-auth** — Not needed. This plugin replaces the original.
701
+
702
+ ---
703
+
704
+ ## Configuration
705
+
706
+ Create `~/.opencode/openai-codex-auth-config.json` for optional settings:
707
+
708
+ ### Model Behavior
709
+
710
+ | Option | Default | What It Does |
711
+ |--------|---------|--------------|
712
+ | `requestTransformMode` | `native` | Request shaping mode: `native` keeps OpenCode payloads unchanged; `legacy` enables Codex compatibility rewrites |
713
+ | `codexMode` | `true` | Legacy-only bridge prompt behavior (applies when `requestTransformMode=legacy`) |
714
+ | `codexTuiV2` | `true` | Enables Codex-style terminal UI output (set `false` for legacy output) |
715
+ | `codexTuiColorProfile` | `truecolor` | Terminal color profile for Codex UI (`truecolor`, `ansi256`, `ansi16`) |
716
+ | `codexTuiGlyphMode` | `ascii` | Glyph mode for Codex UI (`ascii`, `unicode`, `auto`) |
717
+ | `fastSession` | `false` | Forces low-latency settings per request (`reasoningEffort=none/low`, `reasoningSummary=auto`, `textVerbosity=low`) |
718
+ | `fastSessionStrategy` | `hybrid` | `hybrid` speeds simple turns but keeps full-depth on complex prompts; `always` forces fast tuning on every turn |
719
+ | `fastSessionMaxInputItems` | `30` | Max input items kept when fast tuning is applied |
720
+
721
+ ### Account Settings (v4.10.0+)
722
+
723
+ | Option | Default | What It Does |
724
+ |--------|---------|--------------|
725
+ | `perProjectAccounts` | `true` | Each project gets its own account storage namespace under `~/.opencode/projects/` |
726
+ | `toastDurationMs` | `5000` | How long toast notifications stay visible (ms) |
727
+
728
+ ### Retry Behavior
729
+
730
+ | Option | Default | What It Does |
731
+ |--------|---------|--------------|
732
+ | `retryAllAccountsRateLimited` | `true` | Wait and retry when all accounts are rate-limited |
733
+ | `retryAllAccountsMaxWaitMs` | `0` | Max wait time (0 = unlimited) |
734
+ | `retryAllAccountsMaxRetries` | `Infinity` | Max retry attempts |
735
+ | `unsupportedCodexPolicy` | `strict` | Unsupported-model behavior: `strict` (return entitlement error) or `fallback` (retry next model in fallback chain) |
736
+ | `fallbackOnUnsupportedCodexModel` | `false` | Legacy fallback toggle mapped to `unsupportedCodexPolicy` (prefer using `unsupportedCodexPolicy`) |
737
+ | `fallbackToGpt52OnUnsupportedGpt53` | `true` | Legacy compatibility toggle for the `gpt-5.3-codex -> gpt-5.2-codex` edge when generic fallback is enabled |
738
+ | `unsupportedCodexFallbackChain` | `{}` | Optional per-model fallback-chain override (map of `model -> [fallback1, fallback2, ...]`) |
739
+ | `fetchTimeoutMs` | `60000` | Request timeout to Codex backend (ms) |
740
+ | `streamStallTimeoutMs` | `45000` | Abort non-stream parsing if SSE stalls (ms) |
741
+
742
+ Default unsupported-model fallback chain (used when `unsupportedCodexPolicy` is `fallback`):
743
+ - `gpt-5.3-codex -> gpt-5-codex -> gpt-5.2-codex`
744
+ - `gpt-5.3-codex-spark -> gpt-5-codex -> gpt-5.3-codex -> gpt-5.2-codex` (applies if you manually select Spark model IDs)
745
+ - `gpt-5.2-codex -> gpt-5-codex`
746
+ - `gpt-5.1-codex -> gpt-5-codex`
747
+
748
+ ### Environment Variables
749
+
750
+ ```bash
751
+ DEBUG_CODEX_PLUGIN=1 opencode # Enable debug logging
752
+ ENABLE_PLUGIN_REQUEST_LOGGING=1 opencode # Log request metadata
753
+ CODEX_PLUGIN_LOG_BODIES=1 opencode # Include raw request/response payloads in request logs (sensitive)
754
+ CODEX_PLUGIN_LOG_LEVEL=debug opencode # Set log level (debug|info|warn|error)
755
+ CODEX_AUTH_REQUEST_TRANSFORM_MODE=legacy opencode # Re-enable legacy Codex request rewrites
756
+ CODEX_MODE=0 opencode # Temporarily disable bridge prompt
757
+ CODEX_TUI_V2=0 opencode # Disable Codex-style UI (legacy output)
758
+ CODEX_TUI_COLOR_PROFILE=ansi16 opencode # Force UI color profile
759
+ CODEX_TUI_GLYPHS=unicode opencode # Override glyph mode (ascii|unicode|auto)
760
+ CODEX_AUTH_PREWARM=0 opencode # Disable startup prewarm (prompt/instruction cache warmup)
761
+ CODEX_AUTH_FAST_SESSION=1 opencode # Enable faster response defaults
762
+ CODEX_AUTH_FAST_SESSION_STRATEGY=always opencode # Force fast mode for all prompts
763
+ CODEX_AUTH_FAST_SESSION_MAX_INPUT_ITEMS=24 opencode # Tune fast-mode history window
764
+ CODEX_AUTH_UNSUPPORTED_MODEL_POLICY=fallback opencode # Enable generic unsupported-model fallback
765
+ CODEX_AUTH_FALLBACK_UNSUPPORTED_MODEL=1 opencode # Legacy fallback toggle (prefer policy var above)
766
+ CODEX_AUTH_FALLBACK_GPT53_TO_GPT52=0 opencode # Disable only the legacy gpt-5.3 -> gpt-5.2 edge
767
+ CODEX_AUTH_FETCH_TIMEOUT_MS=120000 opencode # Override request timeout
768
+ CODEX_AUTH_STREAM_STALL_TIMEOUT_MS=60000 opencode # Override SSE stall timeout
769
+ ```
770
+
771
+ For all options, see [docs/configuration.md](docs/configuration.md).
772
+
773
+ ---
774
+
775
+ ## Documentation
776
+
777
+ - [Getting Started](docs/getting-started.md) — Complete installation guide
778
+ - [Configuration](docs/configuration.md) — All configuration options
779
+ - [Troubleshooting](docs/troubleshooting.md) — Common issues and fixes
780
+ - [Architecture](docs/development/ARCHITECTURE.md) — How the plugin works
781
+
782
+ ---
783
+
784
+ ## Credits
785
+
786
+ - [numman-ali/opencode-openai-codex-auth](https://github.com/numman-ali/opencode-openai-codex-auth) by [numman-ali](https://github.com/numman-ali) — Original plugin
787
+ - [ndycode](https://github.com/ndycode) — Multi-account support and maintenance
788
+
789
+ ## License
790
+
791
+ MIT License. See [LICENSE](LICENSE) for details.
792
+
793
+ <details>
794
+ <summary><b>Legal</b></summary>
795
+
796
+ ### Intended Use
797
+
798
+ - Personal / internal development only
799
+ - Respect subscription quotas and data handling policies
800
+ - Not for production services or bypassing intended limits
801
+
802
+ ### Warning
803
+
804
+ By using this plugin, you acknowledge:
805
+
806
+ - **Terms of Service risk** — This approach may violate ToS of AI model providers
807
+ - **No guarantees** — APIs may change without notice
808
+ - **Assumption of risk** — You assume all legal, financial, and technical risks
809
+
810
+ ### Disclaimer
811
+
812
+ - Not affiliated with OpenAI. This is an independent open-source project.
813
+ - "ChatGPT", "GPT-5", "Codex", and "OpenAI" are trademarks of OpenAI, L.L.C.
814
+
815
+ </details>