@codexapi/codexclaude 2.0.16 → 2.0.19
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/CUSTOMIZATIONS.md +56 -26
- package/README.md +20 -26
- package/bin/codexclaude.js +291 -48
- package/codexclaude.md +115 -244
- package/package.json +3 -3
package/CUSTOMIZATIONS.md
CHANGED
|
@@ -1,54 +1,84 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Magnetapi Client Customizations
|
|
2
2
|
|
|
3
|
-
`codexclaude`
|
|
3
|
+
`codexclaude` tracks the managed coding runtime while keeping a thin Magnetapi Client launcher layer. Future upgrades must preserve this file's behavior before a package is published.
|
|
4
4
|
|
|
5
5
|
## Runtime
|
|
6
6
|
|
|
7
|
-
- Customer-facing app name: `Magnetapi
|
|
8
|
-
- Local launcher version: `2.0.
|
|
9
|
-
- Bundled official
|
|
10
|
-
-
|
|
7
|
+
- Customer-facing app name: `Magnetapi Client`
|
|
8
|
+
- Local launcher version: `2.0.19`
|
|
9
|
+
- Bundled official runtime dependency: `@openai/codex@0.144.1`
|
|
10
|
+
- Required install command: `npm install -g https://codexapi.pro/downloads/codexapi-codexclaude-2.0.19.tgz`
|
|
11
|
+
- Bundled runtime version is managed internally and must not be used for customer update prompts.
|
|
12
|
+
- Launcher update checks may call the CodexAPI.pro version endpoint and `@codexapi/codexclaude` npm metadata only.
|
|
13
|
+
- The launcher must never check `@openai/codex` npm metadata or OpenAI GitHub releases for update notices.
|
|
11
14
|
|
|
12
15
|
## Launcher Behavior
|
|
13
16
|
|
|
14
|
-
- Authenticates customers against
|
|
15
|
-
- Saves the returned API username in `~/.codexclaude/config.json`.
|
|
17
|
+
- Authenticates customers against the selected or auto-detected dashboard service: CodexAPI.pro, ChatPlus.chat, MyAPI.world, or MagnetAPI.org.
|
|
18
|
+
- Saves the returned API username/System Token in `~/.codexclaude/config.json`.
|
|
16
19
|
- Rewrites `~/.codex/config.toml` before every launch.
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
+
- Deletes stale `~/.codex/version.json` before writing managed config.
|
|
21
|
+
- Launches the bundled platform-native runtime binary directly rather than the upstream npm wrapper.
|
|
22
|
+
- Keeps launcher-owned output branded as `Magnetapi Client`; hardcoded native binary strings require a forked native runtime build if operations wants them removed across all platforms.
|
|
23
|
+
- Starts with `--search` by default.
|
|
24
|
+
- Passes unknown commands directly to the bundled runtime after config is applied.
|
|
25
|
+
- Provides `codexclaude changelog` using the managed version endpoint.
|
|
20
26
|
- Does not expose separate `codexclaude status` or `codexclaude usage` commands; wallet information remains a compact pre-launch line.
|
|
21
|
-
-
|
|
27
|
+
- Version `2.0.19` is forced by the backend minimum version and older clients must show an update-required message.
|
|
22
28
|
|
|
23
29
|
## Provider Config
|
|
24
30
|
|
|
25
|
-
The launcher writes a
|
|
31
|
+
The launcher writes a model provider named `codexapi`:
|
|
26
32
|
|
|
27
|
-
- `base_url
|
|
33
|
+
- `base_url` uses the logged-in service origin. CodexAPI.pro and ChatPlus Claude-family models keep the Chicago Responses endpoint; MyAPI.world and MagnetAPI.org keep their own API endpoints.
|
|
28
34
|
- `wire_api = "responses"`
|
|
29
35
|
- `supports_websockets = false`
|
|
30
36
|
- `experimental_bearer_token` set to the customer API username
|
|
31
|
-
- `http_headers` identify launcher traffic to
|
|
37
|
+
- `http_headers` identify launcher traffic to the backend for server-side plan enforcement
|
|
38
|
+
- `check_for_update_on_startup = false`
|
|
39
|
+
- `analytics_enabled = false`
|
|
40
|
+
- `feedback_enabled = false`
|
|
32
41
|
|
|
33
42
|
## Runtime Defaults
|
|
34
43
|
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
- Service tier: omitted by default; `/fast` remains a user-controlled Codex setting and is billed server-side when active.
|
|
44
|
+
- Default model: `claude-opus-4-8` displayed as `Opus 4.8`
|
|
45
|
+
- Supported launcher choices: `gpt-5.5`, `claude-opus-4-8`, `claude-sonnet-5`, and `claude-fable-5`
|
|
46
|
+
- Reasoning effort displayed locally: `xhigh`
|
|
47
|
+
- Reasoning hint sent in launcher env: `xhigh`
|
|
40
48
|
- Approval policy: `never`
|
|
41
49
|
- Sandbox mode: `danger-full-access`
|
|
50
|
+
- Display wording for permissions: `Full Access` in launcher-owned copy
|
|
51
|
+
- Local model catalog: `~/.codexclaude/model_catalog.json`; this keeps the native `/model` picker limited to the four supported choices and prevents fallback metadata warnings for Opus 4.8, Sonnet 5, and Fable 5.
|
|
52
|
+
- Service tier: omitted by default; `/fast` remains user-controlled and billed server-side when active.
|
|
42
53
|
- TUI status line: `model-with-reasoning`, `fast-mode`, `current-dir`
|
|
43
|
-
-
|
|
44
|
-
- Fable 5 stays visible to the user while the backend applies the custom routed premium path and 2x billing multiplier.
|
|
45
|
-
|
|
46
|
-
Current backend state verified on 2026-07-08: Admin Manage Models controls runtime routing server-side. This operational routing must not change the launcher-visible model ids, model catalog, or customer-facing labels.
|
|
54
|
+
- Fable 5 stays visible to the user while the backend applies its custom routed premium path and billing multiplier.
|
|
47
55
|
|
|
48
56
|
## Wallet Display
|
|
49
57
|
|
|
50
|
-
Before launching
|
|
58
|
+
Before launching the runtime, the launcher calls `/api/v1/wallet/status`, then `/api/v1/me`, then `/api/me` as fallback using the saved API username as bearer token. Wallet lookup failures must not block a local coding session.
|
|
59
|
+
|
|
60
|
+
Expected status line:
|
|
51
61
|
|
|
52
62
|
```text
|
|
53
|
-
|
|
63
|
+
Magnetapi Client v2.0.19 · opus-4.8 xhigh · ~/project · Wallet $20.00
|
|
54
64
|
```
|
|
65
|
+
|
|
66
|
+
## Upgrade Checklist
|
|
67
|
+
|
|
68
|
+
When updating the bundled runtime:
|
|
69
|
+
|
|
70
|
+
1. Update `CODEX_VERSION` in `bin/codexclaude.js`.
|
|
71
|
+
2. Update `@openai/codex` in `package.json` and `package-lock.json`.
|
|
72
|
+
3. Bump the launcher package version.
|
|
73
|
+
4. Keep `APP_DISPLAY_NAME = "Magnetapi Client"`.
|
|
74
|
+
5. Keep `DEFAULT_MODEL_ID = "claude-opus-4-8"`.
|
|
75
|
+
6. Keep `DISPLAY_REASONING_EFFORT = "xhigh"`.
|
|
76
|
+
7. Keep Full Access defaults: `approval_policy = "never"` and `sandbox_mode = "danger-full-access"`.
|
|
77
|
+
8. Keep `check_for_update_on_startup = false`.
|
|
78
|
+
9. Keep `clearUpstreamUpdateCache()` deleting `~/.codex/version.json`.
|
|
79
|
+
10. Keep direct platform binary launch and do not fall back to the upstream npm wrapper.
|
|
80
|
+
11. Keep update checks limited to `/api/v1/codexclaude/version` and `@codexapi/codexclaude` npm metadata.
|
|
81
|
+
12. Keep the four-model `MODELS` map and local model catalog.
|
|
82
|
+
13. Keep bearer username auth and the `X-CodexAPI-*` headers.
|
|
83
|
+
14. Update `README.md`, `CUSTOMIZATIONS.md`, and `codexclaude.md`.
|
|
84
|
+
15. Run `node --check bin/codexclaude.js`, a temporary-home setup test, `npm pack --dry-run`, and endpoint validation before publishing.
|
package/README.md
CHANGED
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
# codexclaude
|
|
2
2
|
|
|
3
|
-
`codexclaude` installs the Magnetapi
|
|
3
|
+
`codexclaude` installs the Magnetapi Client for customers who want one coding CLI that can use ChatGPT-5.5, Opus 4.8, Sonnet 5, or Fable 5 against the same Token Wallet.
|
|
4
4
|
|
|
5
|
-
Version `2.0.
|
|
5
|
+
Version `2.0.19` is a required major sync release. It bundles official Codex runtime dependency `@openai/codex@0.144.1`, launches the platform-native runtime binary directly, disables upstream OpenAI update prompts, and applies account, wallet, model, Full Access, Opus 4.8 default, and xhigh visible reasoning before each coding session starts.
|
|
6
6
|
|
|
7
|
-
## Install
|
|
7
|
+
## Install Or Update
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install -g
|
|
10
|
+
npm install -g https://codexapi.pro/downloads/codexapi-codexclaude-2.0.19.tgz
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
This
|
|
13
|
+
This does not delete local session history. The update replaces the `codexclaude` launcher package, refreshes the bundled runtime dependency, and rewrites the managed provider config the next time `codexclaude setup`, `codexclaude login`, or `codexclaude start` runs.
|
|
14
14
|
|
|
15
15
|
## Update Notices
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
The launcher checks CodexAPI.pro's managed version endpoint and the `@codexapi/codexclaude` npm package metadata only. It must never check `@openai/codex` npm metadata or OpenAI GitHub releases for customer update prompts.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
npm install -g @codexapi/codexclaude@2.0.16
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
This does not delete your local Codex session history. The update only replaces the `codexclaude` launcher and refreshes the CodexAPI.pro provider config.
|
|
19
|
+
Version `2.0.19` is currently enforced as the minimum supported version, so older launchers show a required update message with the exact hosted tarball command above.
|
|
24
20
|
|
|
25
21
|
## First Login
|
|
26
22
|
|
|
@@ -28,7 +24,7 @@ This does not delete your local Codex session history. The update only replaces
|
|
|
28
24
|
codexclaude login
|
|
29
25
|
```
|
|
30
26
|
|
|
31
|
-
Enter the
|
|
27
|
+
Enter the Dashboard Username or Email Address and password. The launcher can log in to CodexAPI.pro, ChatPlus.chat, MyAPI.world, or MagnetAPI.org, then saves the correct System Token locally, writes `~/.codex/config.toml`, sets Full Access defaults, and lets the customer choose the coding model. If the customer presses Enter at the model prompt, Opus 4.8 is selected by default.
|
|
32
28
|
|
|
33
29
|
## Start Coding
|
|
34
30
|
|
|
@@ -56,25 +52,23 @@ Show current launcher changes:
|
|
|
56
52
|
codexclaude changelog
|
|
57
53
|
```
|
|
58
54
|
|
|
59
|
-
##
|
|
55
|
+
## Startup Status
|
|
60
56
|
|
|
61
|
-
Before launching
|
|
57
|
+
Before launching the coding runtime, the app prints a compact status line like:
|
|
62
58
|
|
|
63
59
|
```text
|
|
64
|
-
|
|
60
|
+
Magnetapi Client v2.0.19 · opus-4.8 xhigh · ~/project · Wallet $20.00
|
|
65
61
|
```
|
|
66
62
|
|
|
67
|
-
## Preserved
|
|
63
|
+
## Preserved Customizations
|
|
68
64
|
|
|
69
|
-
- Dashboard
|
|
70
|
-
- ChatGPT-5.5, Opus 4.8, Sonnet 5, or Fable 5 model selection.
|
|
71
|
-
-
|
|
65
|
+
- Dashboard Username or Email Address plus password login for CodexAPI.pro, ChatPlus.chat, MyAPI.world, and MagnetAPI.org.
|
|
66
|
+
- ChatGPT-5.5, Opus 4.8, Sonnet 5, or Fable 5 model selection, with Opus 4.8 as the default.
|
|
67
|
+
- Service-specific Responses-compatible provider for the dashboard account that logged in.
|
|
72
68
|
- Full Access defaults: approval policy `never` and sandbox mode `danger-full-access`.
|
|
73
|
-
- xhigh visible reasoning in the local
|
|
74
|
-
- A local `~/.codexclaude/model_catalog.json` file so native
|
|
75
|
-
- No default fast service tier. Fast mode is billed only when the user enables it inside
|
|
76
|
-
- Magnetapi.org Coding Agent `2.0.16` with the current profile-compatible config enabled.
|
|
69
|
+
- xhigh visible reasoning in the local UI while the API server keeps upstream runtime effort server-managed.
|
|
70
|
+
- A local `~/.codexclaude/model_catalog.json` file so the native `/model` picker lists only ChatGPT-5.5, Opus 4.8, Sonnet 5, and Fable 5.
|
|
71
|
+
- No default fast service tier. Fast mode is billed only when the user enables it inside the client.
|
|
77
72
|
- Token Wallet balance lookup before launch without exposing separate `status` or `usage` launcher commands.
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
- Non-blocking update notices before coding starts, with an explicit update command when a newer recommended launcher exists.
|
|
73
|
+
- Backend-identifying request headers so the API can enforce account and plan rules server-side.
|
|
74
|
+
- Direct platform binary launch so the upstream npm wrapper cannot emit OpenAI update prompts.
|
package/bin/codexclaude.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, chmodSync } from "node:fs";
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, chmodSync, unlinkSync } from "node:fs";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import readline from "node:readline/promises";
|
|
@@ -10,11 +10,12 @@ import { stdin as input, stdout as output } from "node:process";
|
|
|
10
10
|
|
|
11
11
|
const require = createRequire(import.meta.url);
|
|
12
12
|
|
|
13
|
-
const APP_VERSION = "2.0.
|
|
14
|
-
const CODEX_VERSION = "0.
|
|
15
|
-
const APP_DISPLAY_NAME = "Magnetapi
|
|
13
|
+
const APP_VERSION = "2.0.19";
|
|
14
|
+
const CODEX_VERSION = "0.144.1";
|
|
15
|
+
const APP_DISPLAY_NAME = "Magnetapi Client";
|
|
16
|
+
const DEFAULT_MODEL_ID = "claude-opus-4-8";
|
|
16
17
|
const DISPLAY_REASONING_EFFORT = "xhigh";
|
|
17
|
-
const SERVER_REASONING_EFFORT = "
|
|
18
|
+
const SERVER_REASONING_EFFORT = "xhigh";
|
|
18
19
|
const API_ORIGIN = (process.env.CODEXCLAUDE_API_ORIGIN || "https://codexapi.pro").replace(/\/+$/, "");
|
|
19
20
|
const API_BASE_URL = `${API_ORIGIN}/v1`;
|
|
20
21
|
const CHICAGO_API_ORIGIN = "https://api-chicago.codexapi.pro";
|
|
@@ -22,16 +23,44 @@ const CHICAGO_API_BASE_URL = `${CHICAGO_API_ORIGIN}/v1`;
|
|
|
22
23
|
const VERSION_CHECK_PATH = "/api/v1/codexclaude/version";
|
|
23
24
|
const NPM_PACKAGE_NAME = "@codexapi/codexclaude";
|
|
24
25
|
const NPM_LATEST_URL = "https://registry.npmjs.org/@codexapi%2Fcodexclaude/latest";
|
|
25
|
-
const
|
|
26
|
+
const HOSTED_TARBALL_URL = `https://codexapi.pro/downloads/codexapi-codexclaude-${APP_VERSION}.tgz`;
|
|
27
|
+
const UPDATE_COMMAND = `npm install -g ${HOSTED_TARBALL_URL}`;
|
|
26
28
|
const CONFIG_DIR = path.join(homedir(), ".codexclaude");
|
|
27
29
|
const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
28
30
|
const MODEL_CATALOG_FILE = path.join(CONFIG_DIR, "model_catalog.json");
|
|
29
31
|
const CODEX_DIR = path.join(homedir(), ".codex");
|
|
30
32
|
const CODEX_CONFIG_FILE = path.join(CODEX_DIR, "config.toml");
|
|
33
|
+
const CODEX_UPDATE_CACHE_FILE = path.join(CODEX_DIR, "version.json");
|
|
31
34
|
const PROVIDER_ID = "codexapi";
|
|
32
35
|
const MODEL_CATALOG_CONTEXT_WINDOW = 272000;
|
|
36
|
+
const SERVICE_CATALOG = [
|
|
37
|
+
{
|
|
38
|
+
id: "codexapi",
|
|
39
|
+
label: "CodexAPI.pro",
|
|
40
|
+
apiOrigin: "https://codexapi.pro",
|
|
41
|
+
aliases: ["codexapi", "codex", "codexapi.pro", "api.codexapi.pro"],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "chatplus",
|
|
45
|
+
label: "ChatPlus.chat",
|
|
46
|
+
apiOrigin: "https://chatplus.chat",
|
|
47
|
+
aliases: ["chatplus", "chatplus.chat", "chat"],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "myapi",
|
|
51
|
+
label: "MyAPI.world",
|
|
52
|
+
apiOrigin: "https://api.myapi.world",
|
|
53
|
+
aliases: ["myapi", "myapi.world", "api.myapi.world"],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: "magnetapi",
|
|
57
|
+
label: "MagnetAPI.org",
|
|
58
|
+
apiOrigin: "https://api.magnetapi.org",
|
|
59
|
+
aliases: ["magnetapi", "magnet", "magnetapi.org", "api.magnetapi.org"],
|
|
60
|
+
},
|
|
61
|
+
];
|
|
33
62
|
const MODEL_CATALOG_BASE_INSTRUCTIONS = [
|
|
34
|
-
"You are
|
|
63
|
+
"You are Magnetapi Client, a coding agent running in the user's terminal.",
|
|
35
64
|
"You share the user's local workspace, use local tools when available, and complete coding tasks directly and carefully.",
|
|
36
65
|
"Follow the tool schema supplied by the client and keep CodexAPI.pro provider details out of user-facing answers unless the user asks about setup or billing.",
|
|
37
66
|
].join(" ");
|
|
@@ -39,7 +68,7 @@ const SUPPORTED_REASONING_LEVELS = [
|
|
|
39
68
|
{ effort: "low", description: "Fast responses with lighter reasoning" },
|
|
40
69
|
{ effort: "medium", description: "Balances speed and reasoning depth for everyday coding" },
|
|
41
70
|
{ effort: "high", description: "Greater reasoning depth for complex work" },
|
|
42
|
-
{ effort: "xhigh", description: "Extra high visible reasoning setting for
|
|
71
|
+
{ effort: "xhigh", description: "Extra high visible reasoning setting for managed sessions" },
|
|
43
72
|
];
|
|
44
73
|
|
|
45
74
|
const MODELS = {
|
|
@@ -118,12 +147,12 @@ function printHelp() {
|
|
|
118
147
|
${APP_DISPLAY_NAME} ${APP_VERSION}
|
|
119
148
|
|
|
120
149
|
Commands:
|
|
121
|
-
codexclaude login Login with
|
|
150
|
+
codexclaude login Login with dashboard username/email and password
|
|
122
151
|
codexclaude model Select ChatGPT-5.5, Opus 4.8, Sonnet 5, or Fable 5
|
|
123
152
|
codexclaude changelog Show the latest CodexAPI.pro launcher changes
|
|
124
153
|
codexclaude setup Rewrite ~/.codex/config.toml with Full Access defaults
|
|
125
|
-
codexclaude start Start
|
|
126
|
-
codexclaude resume Resume
|
|
154
|
+
codexclaude start Start Magnetapi Client with --search
|
|
155
|
+
codexclaude resume Resume the latest coding session with --search
|
|
127
156
|
codexclaude logout Remove saved codexclaude account state
|
|
128
157
|
|
|
129
158
|
Any other command is passed through to the bundled coding runtime after Magnetapi.org account and model config is applied.
|
|
@@ -151,45 +180,144 @@ async function printChangelog() {
|
|
|
151
180
|
async function loginFlow() {
|
|
152
181
|
const rl = readline.createInterface({ input, output });
|
|
153
182
|
try {
|
|
154
|
-
const username = (await rl.question("
|
|
183
|
+
const username = (await rl.question("Dashboard Username or Email Address: ")).trim();
|
|
155
184
|
const password = await rl.question("Dashboard password: ");
|
|
156
185
|
if (!username || !password) {
|
|
157
186
|
throw new Error("Username/email and password are required.");
|
|
158
187
|
}
|
|
159
|
-
const
|
|
188
|
+
const existing = readConfig();
|
|
189
|
+
const normalizedExisting = normalizeConfig(existing);
|
|
190
|
+
const selectedService = await askService(rl, normalizedExisting?.serviceId);
|
|
191
|
+
const loginResult = await loginWithServiceSelection({
|
|
160
192
|
username,
|
|
161
193
|
password,
|
|
162
|
-
|
|
194
|
+
selectedService,
|
|
195
|
+
currentServiceId: normalizedExisting?.serviceId,
|
|
163
196
|
});
|
|
164
|
-
const
|
|
197
|
+
const { response, service } = loginResult;
|
|
198
|
+
const apiUsername = extractApiUsername(response);
|
|
165
199
|
if (!apiUsername) {
|
|
166
|
-
throw new Error(
|
|
200
|
+
throw new Error(`Login succeeded on ${service.label} but no System Token was returned.`);
|
|
167
201
|
}
|
|
168
|
-
const
|
|
169
|
-
const normalizedExisting = normalizeConfig(existing);
|
|
170
|
-
const selectedModel = await askModel(rl, normalizedExisting?.model || "gpt-5.5");
|
|
202
|
+
const selectedModel = await askModel(rl, normalizedExisting?.model || DEFAULT_MODEL_ID);
|
|
171
203
|
const config = {
|
|
172
204
|
version: APP_VERSION,
|
|
173
|
-
|
|
205
|
+
serviceId: service.id,
|
|
206
|
+
serviceLabel: service.label,
|
|
207
|
+
apiOrigin: service.apiOrigin,
|
|
174
208
|
username: apiUsername,
|
|
175
|
-
dashboardEmail: response?.user?.email || null,
|
|
209
|
+
dashboardEmail: response?.user?.email || response?.cliCredentials?.loginEmail || (username.includes("@") ? username : null),
|
|
176
210
|
model: selectedModel,
|
|
177
211
|
loggedInAt: new Date().toISOString(),
|
|
178
212
|
};
|
|
179
213
|
saveConfig(config);
|
|
180
214
|
writeCodexConfig(config);
|
|
181
|
-
console.log(`\nLogged in as ${apiUsername}. Model: ${MODELS[selectedModel].label}.`);
|
|
182
|
-
console.log("Full Access permissions, xhigh visible reasoning, and
|
|
215
|
+
console.log(`\nLogged in to ${service.label} as ${apiUsername}. Model: ${MODELS[selectedModel].label}.`);
|
|
216
|
+
console.log("Full Access permissions, xhigh visible reasoning, and service-specific provider config were written.");
|
|
183
217
|
} finally {
|
|
184
218
|
rl.close();
|
|
185
219
|
}
|
|
186
220
|
}
|
|
187
221
|
|
|
222
|
+
async function askService(rl, currentServiceId) {
|
|
223
|
+
const current = serviceById(currentServiceId);
|
|
224
|
+
console.log("\nWhich dashboard is this account from?");
|
|
225
|
+
console.log(" 0. Auto-detect across all supported sites");
|
|
226
|
+
SERVICE_CATALOG.forEach((service, index) => {
|
|
227
|
+
const currentMarker = current?.id === service.id ? " (current)" : "";
|
|
228
|
+
console.log(` ${index + 1}. ${service.label}${currentMarker}`);
|
|
229
|
+
});
|
|
230
|
+
const answer = (await rl.question("Dashboard service [Auto-detect]: ")).trim().toLowerCase();
|
|
231
|
+
if (!answer || answer === "0" || answer === "auto" || answer === "detect") {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
const service = serviceFromAnswer(answer);
|
|
235
|
+
if (!service) {
|
|
236
|
+
throw new Error("Unknown dashboard service. Choose 0, 1, 2, 3, or 4.");
|
|
237
|
+
}
|
|
238
|
+
return service;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async function loginWithServiceSelection({ username, password, selectedService, currentServiceId }) {
|
|
242
|
+
const loginBody = {
|
|
243
|
+
username,
|
|
244
|
+
password,
|
|
245
|
+
deviceName: `codexclaude ${APP_VERSION}`,
|
|
246
|
+
};
|
|
247
|
+
if (selectedService) {
|
|
248
|
+
return {
|
|
249
|
+
service: selectedService,
|
|
250
|
+
response: await postJson("/api/v1/auth/login", loginBody, selectedService.apiOrigin),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const candidates = orderedLoginServices(username, currentServiceId);
|
|
254
|
+
const successes = [];
|
|
255
|
+
const failures = [];
|
|
256
|
+
for (const service of candidates) {
|
|
257
|
+
try {
|
|
258
|
+
const response = await postJson("/api/v1/auth/login", loginBody, service.apiOrigin);
|
|
259
|
+
successes.push({ service, response });
|
|
260
|
+
} catch (error) {
|
|
261
|
+
failures.push({ service, error });
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (successes.length === 1) {
|
|
265
|
+
return successes[0];
|
|
266
|
+
}
|
|
267
|
+
if (successes.length > 1) {
|
|
268
|
+
return chooseBestSuccessfulLogin(username, successes);
|
|
269
|
+
}
|
|
270
|
+
const failureSummary = failures
|
|
271
|
+
.map(({ service, error }) => `${service.label}: ${error.message}`)
|
|
272
|
+
.join("; ");
|
|
273
|
+
throw new Error(`Login failed on all supported sites. ${failureSummary}`);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function orderedLoginServices(username, currentServiceId) {
|
|
277
|
+
const lower = String(username || "").trim().toLowerCase();
|
|
278
|
+
const preferred = [];
|
|
279
|
+
const current = serviceById(currentServiceId);
|
|
280
|
+
if (current) {
|
|
281
|
+
preferred.push(current);
|
|
282
|
+
}
|
|
283
|
+
if (lower.startsWith("myapi-")) {
|
|
284
|
+
preferred.push(serviceById("myapi"));
|
|
285
|
+
} else if (lower.startsWith("magnet-") || lower.startsWith("magnetapi-")) {
|
|
286
|
+
preferred.push(serviceById("magnetapi"));
|
|
287
|
+
} else if (lower.startsWith("g2g-codex-") || lower.startsWith("codex-")) {
|
|
288
|
+
preferred.push(serviceById("codexapi"), serviceById("chatplus"));
|
|
289
|
+
}
|
|
290
|
+
return dedupeServices([...preferred.filter(Boolean), ...SERVICE_CATALOG]);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function chooseBestSuccessfulLogin(username, successes) {
|
|
294
|
+
const lower = String(username || "").trim().toLowerCase();
|
|
295
|
+
const exactTokenMatch = successes.find(({ service }) => {
|
|
296
|
+
if (lower.startsWith("myapi-")) return service.id === "myapi";
|
|
297
|
+
if (lower.startsWith("magnet-") || lower.startsWith("magnetapi-")) return service.id === "magnetapi";
|
|
298
|
+
if (lower.startsWith("g2g-codex-") || lower.startsWith("codex-")) return service.id === "codexapi";
|
|
299
|
+
return false;
|
|
300
|
+
});
|
|
301
|
+
return exactTokenMatch || successes[0];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function extractApiUsername(response) {
|
|
305
|
+
return (
|
|
306
|
+
response?.cliCredentials?.apiToken ||
|
|
307
|
+
response?.cliCredentials?.username ||
|
|
308
|
+
response?.user?.apiToken ||
|
|
309
|
+
response?.user?.systemToken ||
|
|
310
|
+
response?.user?.username ||
|
|
311
|
+
response?.apiKey?.token ||
|
|
312
|
+
""
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
188
316
|
async function modelFlow() {
|
|
189
317
|
const config = requireConfig();
|
|
190
318
|
const rl = readline.createInterface({ input, output });
|
|
191
319
|
try {
|
|
192
|
-
config.model = await askModel(rl, config.model ||
|
|
320
|
+
config.model = await askModel(rl, config.model || DEFAULT_MODEL_ID);
|
|
193
321
|
config.version = APP_VERSION;
|
|
194
322
|
saveConfig(config);
|
|
195
323
|
writeCodexConfig(config);
|
|
@@ -217,7 +345,7 @@ async function ensureReady() {
|
|
|
217
345
|
}
|
|
218
346
|
|
|
219
347
|
async function askModel(rl, current) {
|
|
220
|
-
const currentLabel = MODELS[current]?.label || MODELS[
|
|
348
|
+
const currentLabel = MODELS[current]?.label || MODELS[DEFAULT_MODEL_ID].label;
|
|
221
349
|
console.log("\nChoose your coding model:");
|
|
222
350
|
Object.values(MODELS).forEach((model, index) => {
|
|
223
351
|
const premium = model.premium ? " (2x premium billing)" : "";
|
|
@@ -225,7 +353,7 @@ async function askModel(rl, current) {
|
|
|
225
353
|
});
|
|
226
354
|
const answer = (await rl.question(`Model [${currentLabel}]: `)).trim().toLowerCase();
|
|
227
355
|
if (!answer) {
|
|
228
|
-
return MODELS[current] ? current :
|
|
356
|
+
return MODELS[current] ? current : DEFAULT_MODEL_ID;
|
|
229
357
|
}
|
|
230
358
|
const match = Object.values(MODELS).find((model) => model.aliases.includes(answer));
|
|
231
359
|
if (!match) {
|
|
@@ -234,8 +362,8 @@ async function askModel(rl, current) {
|
|
|
234
362
|
return match.id;
|
|
235
363
|
}
|
|
236
364
|
|
|
237
|
-
async function postJson(pathname, body) {
|
|
238
|
-
const response = await fetch(`${API_ORIGIN}${pathname}`, {
|
|
365
|
+
async function postJson(pathname, body, origin = API_ORIGIN) {
|
|
366
|
+
const response = await fetch(`${String(origin || API_ORIGIN).replace(/\/+$/, "")}${pathname}`, {
|
|
239
367
|
method: "POST",
|
|
240
368
|
headers: {
|
|
241
369
|
"content-type": "application/json",
|
|
@@ -374,10 +502,10 @@ function updateRequiredMessage(metadata) {
|
|
|
374
502
|
const latest = metadata?.latestVersion || "latest";
|
|
375
503
|
const minimum = metadata?.minimumVersion || latest;
|
|
376
504
|
return [
|
|
377
|
-
`Update required:
|
|
505
|
+
`Update required: ${APP_DISPLAY_NAME} has updated to codexclaude ${latest}. This major release is required for all users so your local client stays synced with the managed model catalog, Full Access defaults, and provider config.`,
|
|
378
506
|
`Installed codexclaude: ${APP_VERSION}. Required: ${minimum}. Latest: ${latest}.`,
|
|
379
507
|
`Run: ${installCommand}`,
|
|
380
|
-
"Your
|
|
508
|
+
"Your local session history will not be deleted. The update only replaces the codexclaude launcher and rewrites provider config backups.",
|
|
381
509
|
].join("\n");
|
|
382
510
|
}
|
|
383
511
|
|
|
@@ -456,7 +584,8 @@ function writeCodexConfig(config) {
|
|
|
456
584
|
copyFileSync(CODEX_CONFIG_FILE, backup);
|
|
457
585
|
}
|
|
458
586
|
const normalized = normalizeConfig(config);
|
|
459
|
-
|
|
587
|
+
clearUpstreamUpdateCache();
|
|
588
|
+
const model = MODELS[normalized.model] ? normalized.model : DEFAULT_MODEL_ID;
|
|
460
589
|
const providerBaseUrl = providerBaseUrlForConfig(normalized);
|
|
461
590
|
const modelCatalogFile = writeModelCatalog();
|
|
462
591
|
const toml = [
|
|
@@ -465,11 +594,14 @@ function writeCodexConfig(config) {
|
|
|
465
594
|
'preferred_auth_method = "apikey"',
|
|
466
595
|
`model_provider = ${tomlString(PROVIDER_ID)}`,
|
|
467
596
|
`model_reasoning_effort = ${tomlString(DISPLAY_REASONING_EFFORT)}`,
|
|
597
|
+
"check_for_update_on_startup = false",
|
|
598
|
+
"analytics_enabled = false",
|
|
599
|
+
"feedback_enabled = false",
|
|
468
600
|
'approval_policy = "never"',
|
|
469
601
|
'sandbox_mode = "danger-full-access"',
|
|
470
602
|
"",
|
|
471
603
|
`[model_providers.${PROVIDER_ID}]`,
|
|
472
|
-
|
|
604
|
+
`name = ${tomlString(normalized.serviceLabel || "CodexAPI.pro")}`,
|
|
473
605
|
`base_url = ${tomlString(providerBaseUrl)}`,
|
|
474
606
|
`experimental_bearer_token = ${tomlString(normalized.username)}`,
|
|
475
607
|
'wire_api = "responses"',
|
|
@@ -485,6 +617,16 @@ function writeCodexConfig(config) {
|
|
|
485
617
|
writeFileSync(CODEX_CONFIG_FILE, toml, { encoding: "utf8", mode: 0o600 });
|
|
486
618
|
}
|
|
487
619
|
|
|
620
|
+
function clearUpstreamUpdateCache() {
|
|
621
|
+
try {
|
|
622
|
+
if (existsSync(CODEX_UPDATE_CACHE_FILE)) {
|
|
623
|
+
unlinkSync(CODEX_UPDATE_CACHE_FILE);
|
|
624
|
+
}
|
|
625
|
+
} catch {
|
|
626
|
+
// A stale upstream update cache should never block writing the managed config.
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
488
630
|
function writeModelCatalog() {
|
|
489
631
|
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
490
632
|
const catalog = {
|
|
@@ -534,15 +676,15 @@ function modelCatalogEntry(model, index) {
|
|
|
534
676
|
|
|
535
677
|
function modelCatalogDescription(modelId) {
|
|
536
678
|
if (modelId === "claude-opus-4-8") {
|
|
537
|
-
return "
|
|
679
|
+
return "Opus 4.8 coding route with local coding tools and wallet billing.";
|
|
538
680
|
}
|
|
539
681
|
if (modelId === "claude-sonnet-5") {
|
|
540
|
-
return "
|
|
682
|
+
return "Sonnet 5 coding route with local coding tools and wallet billing.";
|
|
541
683
|
}
|
|
542
684
|
if (modelId === "claude-fable-5") {
|
|
543
|
-
return "
|
|
685
|
+
return "Fable 5 premium coding route with local coding tools and wallet billing.";
|
|
544
686
|
}
|
|
545
|
-
return "
|
|
687
|
+
return "ChatGPT-5.5 coding route with local coding tools and wallet billing.";
|
|
546
688
|
}
|
|
547
689
|
|
|
548
690
|
function readConfig() {
|
|
@@ -568,7 +710,7 @@ function saveConfig(config) {
|
|
|
568
710
|
|
|
569
711
|
function logout() {
|
|
570
712
|
saveConfig({ version: APP_VERSION, loggedOutAt: new Date().toISOString() });
|
|
571
|
-
console.log("codexclaude login state removed.
|
|
713
|
+
console.log("codexclaude login state removed. Managed coding config was left untouched.");
|
|
572
714
|
}
|
|
573
715
|
|
|
574
716
|
async function runCodex(args) {
|
|
@@ -595,6 +737,11 @@ async function runCodex(args) {
|
|
|
595
737
|
CODEXCLAUDE_SERVER_REASONING_EFFORT: SERVER_REASONING_EFFORT,
|
|
596
738
|
CODEXCLAUDE_VERSION: APP_VERSION,
|
|
597
739
|
};
|
|
740
|
+
delete env.CODEX_MANAGED_BY_NPM;
|
|
741
|
+
delete env.CODEX_MANAGED_BY_BUN;
|
|
742
|
+
delete env.CODEX_MANAGED_PACKAGE_ROOT;
|
|
743
|
+
env.CODEX_DISABLE_UPDATE_CHECK = "1";
|
|
744
|
+
env.CODEX_CHECK_FOR_UPDATE_ON_STARTUP = "0";
|
|
598
745
|
if (wallet) {
|
|
599
746
|
env.CODEXCLAUDE_WALLET_BALANCE_USD = String(wallet.balance);
|
|
600
747
|
}
|
|
@@ -640,21 +787,38 @@ function resolveCodexLaunch() {
|
|
|
640
787
|
if (bundled) {
|
|
641
788
|
return bundled;
|
|
642
789
|
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
};
|
|
790
|
+
throw new Error(
|
|
791
|
+
`Bundled runtime is missing. Reinstall ${APP_DISPLAY_NAME}: ${UPDATE_COMMAND}`,
|
|
792
|
+
);
|
|
647
793
|
}
|
|
648
794
|
|
|
649
795
|
function resolveBundledCodexLaunch() {
|
|
796
|
+
const platformBinary = resolveBundledCodexBinaryLaunch();
|
|
797
|
+
if (platformBinary) {
|
|
798
|
+
return platformBinary;
|
|
799
|
+
}
|
|
800
|
+
return null;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
function resolveBundledCodexBinaryLaunch() {
|
|
804
|
+
const target = platformCodexTarget();
|
|
805
|
+
if (!target) {
|
|
806
|
+
return null;
|
|
807
|
+
}
|
|
650
808
|
try {
|
|
651
|
-
const packageJsonPath = require.resolve(
|
|
809
|
+
const packageJsonPath = require.resolve(`${target.packageName}/package.json`);
|
|
652
810
|
const packageRoot = path.dirname(packageJsonPath);
|
|
653
|
-
const binPath = path.join(
|
|
811
|
+
const binPath = path.join(
|
|
812
|
+
packageRoot,
|
|
813
|
+
"vendor",
|
|
814
|
+
target.triple,
|
|
815
|
+
"bin",
|
|
816
|
+
process.platform === "win32" ? "codex.exe" : "codex",
|
|
817
|
+
);
|
|
654
818
|
if (existsSync(binPath)) {
|
|
655
819
|
return {
|
|
656
|
-
command:
|
|
657
|
-
argsPrefix: [
|
|
820
|
+
command: binPath,
|
|
821
|
+
argsPrefix: [],
|
|
658
822
|
};
|
|
659
823
|
}
|
|
660
824
|
} catch {
|
|
@@ -663,6 +827,30 @@ function resolveBundledCodexLaunch() {
|
|
|
663
827
|
return null;
|
|
664
828
|
}
|
|
665
829
|
|
|
830
|
+
function platformCodexTarget() {
|
|
831
|
+
const platform = process.platform;
|
|
832
|
+
const arch = process.arch;
|
|
833
|
+
if ((platform === "linux" || platform === "android") && arch === "x64") {
|
|
834
|
+
return { triple: "x86_64-unknown-linux-musl", packageName: "@openai/codex-linux-x64" };
|
|
835
|
+
}
|
|
836
|
+
if ((platform === "linux" || platform === "android") && arch === "arm64") {
|
|
837
|
+
return { triple: "aarch64-unknown-linux-musl", packageName: "@openai/codex-linux-arm64" };
|
|
838
|
+
}
|
|
839
|
+
if (platform === "darwin" && arch === "x64") {
|
|
840
|
+
return { triple: "x86_64-apple-darwin", packageName: "@openai/codex-darwin-x64" };
|
|
841
|
+
}
|
|
842
|
+
if (platform === "darwin" && arch === "arm64") {
|
|
843
|
+
return { triple: "aarch64-apple-darwin", packageName: "@openai/codex-darwin-arm64" };
|
|
844
|
+
}
|
|
845
|
+
if (platform === "win32" && arch === "x64") {
|
|
846
|
+
return { triple: "x86_64-pc-windows-msvc", packageName: "@openai/codex-win32-x64" };
|
|
847
|
+
}
|
|
848
|
+
if (platform === "win32" && arch === "arm64") {
|
|
849
|
+
return { triple: "aarch64-pc-windows-msvc", packageName: "@openai/codex-win32-arm64" };
|
|
850
|
+
}
|
|
851
|
+
return null;
|
|
852
|
+
}
|
|
853
|
+
|
|
666
854
|
async function walletSnapshot(config) {
|
|
667
855
|
const payload =
|
|
668
856
|
await tryGetJsonAuth("/api/v1/wallet/status", config, { timeoutMs: 10000 }) ||
|
|
@@ -740,13 +928,21 @@ function normalizeConfig(config) {
|
|
|
740
928
|
"google-gemini-flash-3.5",
|
|
741
929
|
].includes(normalized.model)
|
|
742
930
|
) {
|
|
743
|
-
normalized.model =
|
|
931
|
+
normalized.model = DEFAULT_MODEL_ID;
|
|
744
932
|
}
|
|
745
933
|
if (!MODELS[normalized.model]) {
|
|
746
|
-
normalized.model =
|
|
934
|
+
normalized.model = DEFAULT_MODEL_ID;
|
|
747
935
|
}
|
|
748
936
|
normalized.version = APP_VERSION;
|
|
749
|
-
|
|
937
|
+
const service = serviceById(normalized.serviceId) || serviceByOrigin(normalized.apiOrigin);
|
|
938
|
+
if (service) {
|
|
939
|
+
normalized.serviceId = service.id;
|
|
940
|
+
normalized.serviceLabel = service.label;
|
|
941
|
+
normalized.apiOrigin = service.apiOrigin;
|
|
942
|
+
} else {
|
|
943
|
+
normalized.apiOrigin = String(normalized.apiOrigin || API_ORIGIN).replace(/\/+$/, "");
|
|
944
|
+
normalized.serviceLabel = normalized.serviceLabel || serviceLabelForOrigin(normalized.apiOrigin);
|
|
945
|
+
}
|
|
750
946
|
return normalized;
|
|
751
947
|
}
|
|
752
948
|
|
|
@@ -775,6 +971,53 @@ function isCodexApiOrigin(origin) {
|
|
|
775
971
|
}
|
|
776
972
|
}
|
|
777
973
|
|
|
974
|
+
function serviceById(id) {
|
|
975
|
+
const normalized = String(id || "").trim().toLowerCase();
|
|
976
|
+
return SERVICE_CATALOG.find((service) => service.id === normalized) || null;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
function serviceByOrigin(origin) {
|
|
980
|
+
const normalized = String(origin || "").trim().replace(/\/+$/, "").toLowerCase();
|
|
981
|
+
if (!normalized) {
|
|
982
|
+
return null;
|
|
983
|
+
}
|
|
984
|
+
return SERVICE_CATALOG.find((service) => service.apiOrigin.toLowerCase() === normalized) || null;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
function serviceFromAnswer(answer) {
|
|
988
|
+
const normalized = String(answer || "").trim().toLowerCase();
|
|
989
|
+
const numbered = Number(normalized);
|
|
990
|
+
if (Number.isInteger(numbered) && numbered >= 1 && numbered <= SERVICE_CATALOG.length) {
|
|
991
|
+
return SERVICE_CATALOG[numbered - 1];
|
|
992
|
+
}
|
|
993
|
+
return SERVICE_CATALOG.find((service) => service.aliases.includes(normalized) || service.id === normalized) || null;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
function dedupeServices(services) {
|
|
997
|
+
const seen = new Set();
|
|
998
|
+
const result = [];
|
|
999
|
+
for (const service of services) {
|
|
1000
|
+
if (!service || seen.has(service.id)) {
|
|
1001
|
+
continue;
|
|
1002
|
+
}
|
|
1003
|
+
seen.add(service.id);
|
|
1004
|
+
result.push(service);
|
|
1005
|
+
}
|
|
1006
|
+
return result;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
function serviceLabelForOrigin(origin) {
|
|
1010
|
+
const service = serviceByOrigin(origin);
|
|
1011
|
+
if (service) {
|
|
1012
|
+
return service.label;
|
|
1013
|
+
}
|
|
1014
|
+
try {
|
|
1015
|
+
return new URL(origin || API_ORIGIN).hostname;
|
|
1016
|
+
} catch {
|
|
1017
|
+
return "CodexAPI.pro";
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
|
|
778
1021
|
function formatUsd(value) {
|
|
779
1022
|
return `$${Number(value || 0).toLocaleString("en-US", {
|
|
780
1023
|
minimumFractionDigits: 2,
|
package/codexclaude.md
CHANGED
|
@@ -1,137 +1,85 @@
|
|
|
1
1
|
# codexclaude Customization Ledger
|
|
2
2
|
|
|
3
|
-
This file
|
|
4
|
-
upgrade of the bundled coding runtime dependency. Treat it as the handoff
|
|
5
|
-
document for future maintainers. The launcher should remain a thin wrapper
|
|
6
|
-
around official `@openai/codex`; do not patch the native Codex binary unless
|
|
7
|
-
there is no supported configuration or API boundary that can solve the issue.
|
|
3
|
+
This file is the durable handoff for the `@codexapi/codexclaude` package in `/root/codexclaude`. Read it before updating the bundled coding runtime. The package is a managed launcher around the official runtime dependency, but customer-facing startup, update, model, auth, and setup behavior must stay under MagnetAPI control.
|
|
8
4
|
|
|
9
5
|
## Current Release
|
|
10
6
|
|
|
11
|
-
-
|
|
12
|
-
- Launcher version: `2.0.
|
|
13
|
-
- Customer-facing app name: `Magnetapi
|
|
14
|
-
- Bundled runtime dependency:
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
7
|
+
- Package name: `@codexapi/codexclaude`
|
|
8
|
+
- Launcher version: `2.0.19`
|
|
9
|
+
- Customer-facing app name: `Magnetapi Client`
|
|
10
|
+
- Bundled runtime dependency: `@openai/codex@0.144.1`
|
|
11
|
+
- Required install command: `npm install -g https://codexapi.pro/downloads/codexapi-codexclaude-2.0.19.tgz`
|
|
12
|
+
- Backend minimum version: `2.0.19`
|
|
13
|
+
- Default visible model: `Opus 4.8`
|
|
14
|
+
- Default model slug: `claude-opus-4-8`
|
|
15
|
+
- Visible reasoning effort: `xhigh`
|
|
16
|
+
- Local permissions: Full Access, implemented as `approval_policy = "never"` and `sandbox_mode = "danger-full-access"`
|
|
19
17
|
- Local launcher state: `~/.codexclaude/config.json`
|
|
20
|
-
- Generated
|
|
21
|
-
- Generated
|
|
18
|
+
- Generated runtime config: `~/.codex/config.toml`
|
|
19
|
+
- Generated model catalog: `~/.codexclaude/model_catalog.json`
|
|
20
|
+
- Upstream update cache removed before setup: `~/.codex/version.json`
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
## Required Customer Behavior
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
The launcher must present itself as:
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
- `claude-opus-4-8` displayed as `Opus 4.8`
|
|
31
|
-
- `claude-sonnet-5` displayed as `Sonnet 5`
|
|
32
|
-
- `claude-fable-5` displayed as `Fable 5`
|
|
33
|
-
|
|
34
|
-
The launcher command `codexclaude model` must list only those four options.
|
|
35
|
-
The native Codex `/model` picker must also list only those four options. This
|
|
36
|
-
is enforced by writing `model_catalog_json` in `~/.codex/config.toml` and
|
|
37
|
-
creating a complete Codex-compatible catalog at
|
|
38
|
-
`~/.codexclaude/model_catalog.json`.
|
|
39
|
-
|
|
40
|
-
Do not rely only on the wrapper prompt for model restrictions. Native Codex can
|
|
41
|
-
render its own model picker from model metadata. If the generated catalog is
|
|
42
|
-
removed, corrupted, or not referenced by `model_catalog_json`, Codex may fall
|
|
43
|
-
back to its bundled OpenAI model list or may warn that metadata for
|
|
44
|
-
`claude-opus-4-8` cannot be found.
|
|
45
|
-
|
|
46
|
-
## Opus 4.8 Metadata Warning Fix
|
|
26
|
+
```text
|
|
27
|
+
Magnetapi Client v2.0.19
|
|
28
|
+
```
|
|
47
29
|
|
|
48
|
-
|
|
30
|
+
Normal pre-launch status should look like:
|
|
49
31
|
|
|
50
32
|
```text
|
|
51
|
-
|
|
33
|
+
Magnetapi Client v2.0.19 · opus-4.8 xhigh · ~/project · Wallet $20.00
|
|
52
34
|
```
|
|
53
35
|
|
|
54
|
-
|
|
55
|
-
model metadata catalog. The fix is not to rename Opus to GPT-5.5 locally,
|
|
56
|
-
because the request body model is how CodexAPI.pro snapshots routing and
|
|
57
|
-
billing before generation starts. The correct fix is to provide valid metadata
|
|
58
|
-
for `claude-opus-4-8`.
|
|
59
|
-
|
|
60
|
-
`bin/codexclaude.js` writes a local catalog with full metadata for all four
|
|
61
|
-
supported slugs. Each entry must include, at minimum:
|
|
62
|
-
|
|
63
|
-
- `slug`
|
|
64
|
-
- `display_name`
|
|
65
|
-
- `description`
|
|
66
|
-
- `default_reasoning_level`
|
|
67
|
-
- `supported_reasoning_levels`
|
|
68
|
-
- `shell_type`
|
|
69
|
-
- `visibility`
|
|
70
|
-
- `supported_in_api`
|
|
71
|
-
- `priority`
|
|
72
|
-
- `base_instructions`
|
|
73
|
-
- `truncation_policy`
|
|
74
|
-
- `supports_parallel_tool_calls`
|
|
75
|
-
- `supports_image_detail_original`
|
|
76
|
-
- `input_modalities`
|
|
77
|
-
- `additional_speed_tiers`
|
|
78
|
-
|
|
79
|
-
Keep `visibility = "list"` for the four supported entries. Do not include any
|
|
80
|
-
other list-visible models in this catalog.
|
|
81
|
-
|
|
82
|
-
## Reasoning Display Versus Server Runtime
|
|
83
|
-
|
|
84
|
-
The user-facing Codex UI must show `xhigh` reasoning. The generated
|
|
85
|
-
`~/.codex/config.toml` therefore writes:
|
|
36
|
+
Do not show OpenAI update notices, OpenAI npm install commands, OpenAI release links, or the upstream runtime version in launcher-owned output. The package still depends on the official runtime internally, but the customer update surface is ours.
|
|
86
37
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
38
|
+
The launcher command `codexclaude model` must list exactly four customer-visible models:
|
|
39
|
+
|
|
40
|
+
- `gpt-5.5` displayed as `ChatGPT-5.5`
|
|
41
|
+
- `claude-opus-4-8` displayed as `Opus 4.8`
|
|
42
|
+
- `claude-sonnet-5` displayed as `Sonnet 5`
|
|
43
|
+
- `claude-fable-5` displayed as `Fable 5`
|
|
90
44
|
|
|
91
|
-
The
|
|
92
|
-
This is handled in the CodexAPI.pro backend by normalizing Responses requests
|
|
93
|
-
to `settings.agent_default_effort`, currently `high`. Do not change the server
|
|
94
|
-
setting just because the launcher displays `xhigh`.
|
|
45
|
+
Opus 4.8 must be the default when a new config is created or a legacy config contains an unsupported Gemini/Deepseek value. The selected model slug must stay in `~/.codex/config.toml`; do not rewrite Opus, Sonnet, or Fable to GPT locally just because the backend may route internally.
|
|
95
46
|
|
|
96
|
-
|
|
47
|
+
## Update Policy
|
|
97
48
|
|
|
98
|
-
|
|
99
|
-
- `SERVER_REASONING_EFFORT = "high"`
|
|
49
|
+
`bin/codexclaude.js` may check:
|
|
100
50
|
|
|
101
|
-
|
|
51
|
+
- `https://codexapi.pro/api/v1/codexclaude/version`
|
|
52
|
+
- `https://registry.npmjs.org/@codexapi%2Fcodexclaude/latest`
|
|
102
53
|
|
|
103
|
-
|
|
54
|
+
It must not check `@openai/codex` npm metadata, OpenAI GitHub releases, or any upstream OpenAI update endpoint. Version `2.0.19` is a forced release: the backend `minimumVersion` equals `2.0.19`, and older clients must show an update-required message with the hosted tarball command.
|
|
104
55
|
|
|
105
|
-
The
|
|
106
|
-
Codex can show `/fast` as active when the user enables it. CodexAPI.pro treats
|
|
107
|
-
fast mode as a billing hint only. The backend must bill fast sessions at the
|
|
108
|
-
configured multiplier, currently `6x`, while stripping fast mode and service
|
|
109
|
-
tier controls before forwarding the request upstream.
|
|
56
|
+
The launcher writes `check_for_update_on_startup = false` and removes `~/.codex/version.json` so the bundled runtime does not display stale upstream update prompts. The launcher also resolves the platform-native runtime binary directly from the optional package (`@openai/codex-linux-x64`, `@openai/codex-darwin-arm64`, and so on). Do not fall back to the upstream npm wrapper, because that wrapper can re-enable upstream managed update behavior.
|
|
110
57
|
|
|
111
|
-
|
|
112
|
-
user-controlled.
|
|
58
|
+
The optional platform-native runtime packages can still contain upstream README files and hardcoded native strings inside the binary. Launcher-owned output must say `Magnetapi Client`; replacing native binary text itself requires a maintained forked native runtime build for every supported platform. Until such a fork exists, do not re-enable the upstream npm wrapper and do not present upstream update notices to customers.
|
|
113
59
|
|
|
114
60
|
## Generated Config Contract
|
|
115
61
|
|
|
116
|
-
`bin/codexclaude.js` must rewrite `~/.codex/config.toml` before every coding
|
|
117
|
-
session. Preserve this top-level shape:
|
|
62
|
+
`bin/codexclaude.js` must rewrite `~/.codex/config.toml` before every coding session. Preserve this top-level shape:
|
|
118
63
|
|
|
119
64
|
```toml
|
|
120
|
-
model = "
|
|
65
|
+
model = "claude-opus-4-8"
|
|
121
66
|
model_catalog_json = "<absolute path to ~/.codexclaude/model_catalog.json>"
|
|
122
67
|
preferred_auth_method = "apikey"
|
|
123
68
|
model_provider = "codexapi"
|
|
124
69
|
model_reasoning_effort = "xhigh"
|
|
70
|
+
check_for_update_on_startup = false
|
|
71
|
+
analytics_enabled = false
|
|
72
|
+
feedback_enabled = false
|
|
125
73
|
approval_policy = "never"
|
|
126
74
|
sandbox_mode = "danger-full-access"
|
|
127
75
|
|
|
128
76
|
[model_providers.codexapi]
|
|
129
|
-
name = "
|
|
130
|
-
base_url = "<
|
|
131
|
-
experimental_bearer_token = "<customer
|
|
77
|
+
name = "<logged-in service label>"
|
|
78
|
+
base_url = "<service Responses URL>"
|
|
79
|
+
experimental_bearer_token = "<customer System Token/API username>"
|
|
132
80
|
wire_api = "responses"
|
|
133
81
|
supports_websockets = false
|
|
134
|
-
http_headers = { "X-CodexAPI-Client" = "codexclaude", "X-CodexAPI-Client-Version" = "
|
|
82
|
+
http_headers = { "X-CodexAPI-Client" = "codexclaude", "X-CodexAPI-Client-Version" = "2.0.19", "X-CodexAPI-Selected-Model" = "<selected model>" }
|
|
135
83
|
|
|
136
84
|
[tui]
|
|
137
85
|
status_line = ["model-with-reasoning", "fast-mode", "current-dir"]
|
|
@@ -139,192 +87,115 @@ status_line_use_colors = true
|
|
|
139
87
|
terminal_title = ["project-name", "model-with-reasoning", "run-state"]
|
|
140
88
|
```
|
|
141
89
|
|
|
142
|
-
The
|
|
143
|
-
config model to `gpt-5.5` when Opus, Sonnet, or Fable is selected. The backend can
|
|
144
|
-
route any selected model through GPT-5.5 or another upstream internally, but the
|
|
145
|
-
client request must preserve the user-facing selected slug for display,
|
|
146
|
-
snapshotting, and billing records.
|
|
147
|
-
|
|
148
|
-
## Routing Rules
|
|
149
|
-
|
|
150
|
-
`gpt-5.5` uses the configured API origin, normally `https://codexapi.pro/v1`.
|
|
151
|
-
|
|
152
|
-
Claude-family codexclaude models use the CodexAPI.pro Claude-compatible Responses endpoint for CodexAPI.pro and ChatPlus accounts. MyAPI.world accounts keep their own configured `api.myapi.world` Responses endpoint.
|
|
153
|
-
|
|
154
|
-
`claude-fable-5` is a premium customer-visible model. The backend bills it at the configured 2x multiplier and routes it through the Admin-selected Fable 5 route while preserving `claude-fable-5` in client-visible status and usage records.
|
|
155
|
-
|
|
156
|
-
The launcher must send these headers for every model:
|
|
90
|
+
The generated model catalog must contain full metadata for the four supported slugs. This prevents fallback metadata warnings such as:
|
|
157
91
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
The backend uses these headers to enforce plan restrictions and to serve the
|
|
163
|
-
codexclaude-specific model catalog from `/v1/models` if native Codex refreshes
|
|
164
|
-
remote metadata.
|
|
165
|
-
|
|
166
|
-
## Authentication And Wallet
|
|
92
|
+
```text
|
|
93
|
+
Model metadata for `claude-opus-4-8` not found. Defaulting to fallback metadata; this can degrade performance and cause issues.
|
|
94
|
+
```
|
|
167
95
|
|
|
168
|
-
|
|
96
|
+
Each model catalog entry must include a slug, display name, reasoning levels including `xhigh`, shell tool type, input modalities including images, web/search support, truncation policy, and `visibility = "list"`.
|
|
169
97
|
|
|
170
|
-
|
|
171
|
-
codexclaude login
|
|
172
|
-
```
|
|
98
|
+
## Service Login
|
|
173
99
|
|
|
174
|
-
The
|
|
100
|
+
The login prompt must ask for:
|
|
175
101
|
|
|
176
102
|
```text
|
|
177
|
-
|
|
103
|
+
Dashboard Username or Email Address:
|
|
178
104
|
```
|
|
179
105
|
|
|
180
|
-
The
|
|
181
|
-
as `experimental_bearer_token` in `~/.codex/config.toml`. Preserve this
|
|
182
|
-
behavior unless the backend auth contract is deliberately changed. The launcher
|
|
183
|
-
must not ask customers for a separate OpenAI key.
|
|
106
|
+
The launcher supports CodexAPI.pro, ChatPlus.chat, MyAPI.world, and MagnetAPI.org. It can auto-detect by trying the supported dashboard auth endpoints. It saves `serviceId`, `serviceLabel`, `apiOrigin`, `username`, optional `dashboardEmail`, selected `model`, and `loggedInAt` in `~/.codexclaude/config.json`.
|
|
184
107
|
|
|
185
|
-
|
|
108
|
+
The saved `username` is the System Token/API username returned by the service and is used as the bearer value. Do not store dashboard session tokens in the launcher config.
|
|
186
109
|
|
|
187
|
-
|
|
188
|
-
/api/v1/wallet/status
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
If that endpoint fails, fall back to:
|
|
110
|
+
## Routing Expectations
|
|
192
111
|
|
|
193
|
-
|
|
194
|
-
/api/v1/me
|
|
195
|
-
```
|
|
112
|
+
The launcher is not the source of truth for upstream runtime routing. Admin Manage Models controls execution routing server-side. The launcher must preserve the user-selected model slug and pass it through the Responses request so billing, logs, and the dashboard can record what the user chose.
|
|
196
113
|
|
|
197
|
-
|
|
114
|
+
CodexAPI.pro and ChatPlus Claude-family models use the CodexAPI.pro Claude-compatible Responses endpoint. MyAPI.world and MagnetAPI.org accounts keep their own API origins. Fable 5 remains visible as `claude-fable-5` while the backend applies the premium model behavior and billing.
|
|
198
115
|
|
|
199
116
|
## Upgrade Checklist
|
|
200
117
|
|
|
201
|
-
When
|
|
202
|
-
|
|
203
|
-
1.
|
|
204
|
-
2.
|
|
205
|
-
3.
|
|
206
|
-
4.
|
|
207
|
-
5. Preserve `
|
|
208
|
-
6. Preserve `
|
|
209
|
-
7. Preserve
|
|
210
|
-
8. Preserve
|
|
211
|
-
9. Preserve
|
|
212
|
-
10. Preserve
|
|
213
|
-
11. Preserve
|
|
214
|
-
12.
|
|
215
|
-
13. Update
|
|
216
|
-
14.
|
|
118
|
+
When updating the bundled runtime dependency:
|
|
119
|
+
|
|
120
|
+
1. Confirm the intended upstream package version with `npm view @openai/codex version`.
|
|
121
|
+
2. Run `npm install @openai/codex@<version> --save-exact`.
|
|
122
|
+
3. Bump `package.json` and `package-lock.json` to a new `@codexapi/codexclaude` version.
|
|
123
|
+
4. Update `APP_VERSION` and `CODEX_VERSION` in `bin/codexclaude.js`.
|
|
124
|
+
5. Preserve `APP_DISPLAY_NAME = "Magnetapi Client"`.
|
|
125
|
+
6. Preserve `DEFAULT_MODEL_ID = "claude-opus-4-8"`.
|
|
126
|
+
7. Preserve `DISPLAY_REASONING_EFFORT = "xhigh"` and `SERVER_REASONING_EFFORT = "xhigh"` unless operations explicitly changes the launcher-visible contract.
|
|
127
|
+
8. Preserve Full Access defaults and the local model catalog.
|
|
128
|
+
9. Preserve direct platform-native binary launch.
|
|
129
|
+
10. Preserve update checks through our version endpoint and `@codexapi/codexclaude` npm metadata only.
|
|
130
|
+
11. Preserve deletion of `~/.codex/version.json` and `check_for_update_on_startup = false`.
|
|
131
|
+
12. Update customer setup scripts on CodexAPI.pro, ChatPlus.chat, MyAPI.world, MagnetAPI.org, and VIP pages to use the exact hosted tarball command.
|
|
132
|
+
13. Update backend `CODEXCLAUDE_LATEST_VERSION`, `CODEXCLAUDE_MIN_VERSION`, and hosted tarball URL.
|
|
133
|
+
14. Update this file, `README.md`, and `CUSTOMIZATIONS.md`.
|
|
134
|
+
15. Run validation and publish.
|
|
217
135
|
|
|
218
136
|
## Validation Commands
|
|
219
137
|
|
|
220
|
-
Run
|
|
138
|
+
Run from `/root/codexclaude`:
|
|
221
139
|
|
|
222
140
|
```bash
|
|
223
141
|
node --check bin/codexclaude.js
|
|
142
|
+
npm pack --dry-run
|
|
224
143
|
```
|
|
225
144
|
|
|
226
|
-
|
|
227
|
-
model catalog entries without making a model call:
|
|
145
|
+
Temporary-home config validation:
|
|
228
146
|
|
|
229
147
|
```bash
|
|
230
148
|
tmp_home="$(mktemp -d)"
|
|
231
|
-
|
|
149
|
+
mkdir -p "$tmp_home/.codexclaude"
|
|
150
|
+
cat > "$tmp_home/.codexclaude/config.json" <<'JSON'
|
|
151
|
+
{
|
|
152
|
+
"version": "2.0.19",
|
|
153
|
+
"serviceId": "codexapi",
|
|
154
|
+
"serviceLabel": "CodexAPI.pro",
|
|
155
|
+
"apiOrigin": "https://codexapi.pro",
|
|
156
|
+
"username": "test-token",
|
|
157
|
+
"dashboardEmail": null,
|
|
158
|
+
"model": "claude-opus-4-8",
|
|
159
|
+
"loggedInAt": "2026-07-10T00:00:00.000Z"
|
|
160
|
+
}
|
|
161
|
+
JSON
|
|
162
|
+
HOME="$tmp_home" CODEXCLAUDE_DISABLE_UPDATE_CHECK=1 CODEXCLAUDE_QUIET_STATUS=1 node bin/codexclaude.js setup
|
|
232
163
|
```
|
|
233
164
|
|
|
234
|
-
|
|
165
|
+
Verify the generated config contains:
|
|
235
166
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
167
|
+
- `model = "claude-opus-4-8"`
|
|
168
|
+
- `model_reasoning_effort = "xhigh"`
|
|
169
|
+
- `check_for_update_on_startup = false`
|
|
170
|
+
- `approval_policy = "never"`
|
|
171
|
+
- `sandbox_mode = "danger-full-access"`
|
|
172
|
+
- no default fast service tier
|
|
239
173
|
|
|
240
|
-
|
|
174
|
+
Verify the generated model catalog contains only:
|
|
241
175
|
|
|
242
176
|
- `gpt-5.5`
|
|
243
177
|
- `claude-opus-4-8`
|
|
244
178
|
- `claude-sonnet-5`
|
|
245
179
|
- `claude-fable-5`
|
|
246
180
|
|
|
247
|
-
|
|
248
|
-
fallback metadata.
|
|
249
|
-
|
|
250
|
-
Package validation:
|
|
181
|
+
After packaging, copy the tarball to the public downloads directories, restart the backend, and verify:
|
|
251
182
|
|
|
252
183
|
```bash
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
Backend validation after changing `/v1/models` or version metadata:
|
|
258
|
-
|
|
259
|
-
```bash
|
|
260
|
-
python3 -m py_compile app/main.py app/openai_compat.py app/config.py app/postgres_admin.py
|
|
261
|
-
/root/codexapi/.venv/bin/pytest -q tests/test_openai_compat.py tests/test_main_helpers.py
|
|
184
|
+
curl -fsS "https://codexapi.pro/api/v1/codexclaude/version?current=2.0.17"
|
|
185
|
+
curl -fsSI "https://codexapi.pro/downloads/codexapi-codexclaude-2.0.19.tgz"
|
|
262
186
|
```
|
|
263
187
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
- Updated the bundled official Codex dependency to `@openai/codex@0.143.0`.
|
|
267
|
-
- Kept the launcher model picker and native Codex `/model` catalog limited to ChatGPT-5.5, Opus 4.8, Sonnet 5, and Fable 5.
|
|
268
|
-
- Kept the customer-facing startup identity as Magnetapi.org Coding Agent and continued hiding the upstream Codex runtime version in normal startup text.
|
|
269
|
-
- Changed the update surface for this release to a recommended, non-blocking notice. Users should be shown the exact update command, but they must not be forced off `2.0.15` for this release.
|
|
270
|
-
- Preserved Full Access defaults, xhigh visible reasoning, bearer username auth, Responses wire API, and the CodexAPI.pro identification headers.
|
|
271
|
-
|
|
272
|
-
## Version 2.0.15 Changes
|
|
273
|
-
|
|
274
|
-
- Renamed the launcher-controlled startup/status surface to Magnetapi.org Coding Agent and now prints the app version instead of the upstream runtime version.
|
|
275
|
-
- Removed Gemini Flash and Deepseek from the launcher model picker and generated native Codex model catalog.
|
|
276
|
-
- Kept ChatGPT-5.5, Opus 4.8, Sonnet 5, and Fable 5 as the only visible codexclaude model choices.
|
|
277
|
-
- Preserved Full Access defaults, xhigh visible reasoning, wallet auth, local model catalog metadata, and CodexAPI.pro identifying headers.
|
|
278
|
-
|
|
279
|
-
## Version 2.0.14 Changes
|
|
280
|
-
|
|
281
|
-
- Updated the official OpenAI Codex runtime dependency to `@openai/codex@0.142.5`, the latest version currently published on npm.
|
|
282
|
-
- Kept `claude-sonnet-5` and `claude-fable-5` as the live API slugs for Sonnet 5 and Fable 5 after verifying those names from the production model APIs.
|
|
283
|
-
- Removed the standalone `codexclaude status` and `codexclaude usage` launcher commands while preserving the compact wallet status line printed before a coding session starts.
|
|
284
|
-
- Preserved Full Access defaults, xhigh visible reasoning, server-managed high runtime effort, bearer username auth, local model catalog metadata, and CodexAPI.pro identifying headers.
|
|
285
|
-
|
|
286
|
-
## Version 2.0.13 Changes
|
|
287
|
-
|
|
288
|
-
- Updated the official OpenAI Codex runtime dependency to `@openai/codex@0.142.2`.
|
|
289
|
-
- Added Sonnet 5 and Fable 5 as visible launcher and native Codex `/model` choices.
|
|
290
|
-
- Added `codexclaude usage`, which reads wallet and recent token usage from the signed-in account origin, including CodexAPI.pro, ChatPlus, or MyAPI.world compatible endpoints.
|
|
291
|
-
- Kept Fable 5 customer-visible while the backend applies its custom routed premium path and 2x billing multiplier.
|
|
292
|
-
- Preserved Full Access defaults, xhigh visible reasoning, server-managed high runtime effort, wallet auth, and local model catalog metadata.
|
|
293
|
-
|
|
294
|
-
## Version 2.0.12 Changes
|
|
295
|
-
|
|
296
|
-
- Updated the official OpenAI Codex runtime dependency to `@openai/codex@0.141.0`.
|
|
297
|
-
- Added Google Gemini Flash 3.5 as a fourth visible launcher and native Codex `/model` choice.
|
|
298
|
-
- Kept Gemini visible in client config, response metadata, and usage records while the backend routes it through Sonnet 5 low effort.
|
|
299
|
-
- Preserved the CodexAPI.pro launcher layer, Full Access defaults, xhigh visible reasoning, server-managed low runtime effort, wallet auth, and Opus 4.8 Chicago routing.
|
|
300
|
-
|
|
301
|
-
## Version 2.0.11 Changes
|
|
302
|
-
|
|
303
|
-
- Updated the official OpenAI Codex runtime dependency to `@openai/codex@0.140.0`.
|
|
304
|
-
- Re-applied the CodexAPI.pro launcher layer without changing the supported model list, local model catalog, Full Access defaults, xhigh visible reasoning, server-managed low runtime effort, fast-mode billing contract, wallet auth, or Opus 4.8 Chicago routing.
|
|
305
|
-
|
|
306
|
-
## Version 2.0.10 Changes
|
|
307
|
-
|
|
308
|
-
- Added a generated local model catalog for native Codex.
|
|
309
|
-
- Limited native Codex `/model` to ChatGPT-5.5, Opus 4.8, and Deepseek v4 Budget.
|
|
310
|
-
- Added valid metadata for `claude-opus-4-8` and `deepseek-v4-pro`.
|
|
311
|
-
- Changed the user-visible reasoning effort from `low` to `xhigh`.
|
|
312
|
-
- Kept server-side upstream reasoning pinned to `low`.
|
|
313
|
-
- Kept `/fast` client-visible by advertising the `fast` speed tier locally while relying on the backend to bill and strip it upstream.
|
|
314
|
-
|
|
315
|
-
## Older Release Notes
|
|
316
|
-
|
|
317
|
-
Version 2.0.9 updated the official Codex runtime dependency to
|
|
318
|
-
`@openai/codex@0.139.0` and re-applied the CodexAPI.pro launcher layer.
|
|
319
|
-
|
|
320
|
-
Version 2.0.8 kept official Codex on `0.137.0`, changed generated config to low
|
|
321
|
-
reasoning, and removed default fast service tier.
|
|
322
|
-
|
|
323
|
-
Version 2.0.7 updated official Codex to `0.137.0`.
|
|
324
|
-
|
|
325
|
-
Version 2.0.6 updated official Codex to `0.135.0`, migrated Opus 4.7 aliases to
|
|
326
|
-
Opus 4.8, and pinned Opus 4.8 codexclaude sessions to Chicago.
|
|
188
|
+
The version endpoint must report `latestVersion = 2.0.19`, `minimumVersion = 2.0.19`, and `updateRequired = true` for old clients.
|
|
327
189
|
|
|
328
|
-
Version 2.0.
|
|
190
|
+
## Version 2.0.19 Changes
|
|
329
191
|
|
|
330
|
-
|
|
192
|
+
- Updated bundled runtime dependency to `@openai/codex@0.144.1`.
|
|
193
|
+
- Forced all older codexclaude clients to update by setting backend minimum version to `2.0.19`.
|
|
194
|
+
- Changed launcher-owned identity to `Magnetapi Client`.
|
|
195
|
+
- Changed the default selected model to Opus 4.8.
|
|
196
|
+
- Kept visible reasoning at xhigh.
|
|
197
|
+
- Preserved Full Access defaults.
|
|
198
|
+
- Disabled bundled runtime update checks through generated config and stale update-cache removal.
|
|
199
|
+
- Removed launcher fallback to the upstream npm wrapper so OpenAI update prompts are not emitted by codexclaude.
|
|
200
|
+
- Kept update monitoring limited to CodexAPI.pro version metadata and the `@codexapi/codexclaude` npm package.
|
|
201
|
+
- Updated setup scripts to install the exact hosted `2.0.19` tarball.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codexapi/codexclaude",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "Magnetapi
|
|
3
|
+
"version": "2.0.19",
|
|
4
|
+
"description": "Magnetapi Client launcher for ChatGPT-5.5, Opus 4.8, Sonnet 5, and Fable 5.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"node": ">=20"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@openai/codex": "0.
|
|
20
|
+
"@openai/codex": "0.144.1"
|
|
21
21
|
},
|
|
22
22
|
"publishConfig": {
|
|
23
23
|
"access": "public"
|