@codexapi/codexclaude 2.0.37 → 2.0.39
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 +10 -8
- package/README.md +10 -7
- package/bin/codexclaude.js +85 -81
- package/bin/splash.js +36 -0
- package/bin/update.js +94 -0
- package/codexclaude.md +59 -0
- package/package.json +4 -3
package/CUSTOMIZATIONS.md
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
## Runtime
|
|
6
6
|
|
|
7
7
|
- Customer-facing app name: `MagnetAPI.org Codex CLI`
|
|
8
|
-
- Local launcher version: `2.0.
|
|
9
|
-
- Bundled official runtime dependency: `@openai/codex@0.
|
|
8
|
+
- Local launcher version: `2.0.39`
|
|
9
|
+
- Bundled official runtime dependency: `@openai/codex@0.154.0`
|
|
10
10
|
- Required install command: `npm install -g @codexapi/codexclaude@latest`
|
|
11
|
-
- Hosted fallback: `
|
|
11
|
+
- Hosted fallback archive: `https://codexapi.pro/downloads/codexapi-codexclaude-2.0.39.tgz`, with its SHA-256 sidecar. The updater installs a verified local copy, not an npm remote URL.
|
|
12
12
|
- Bundled runtime version is managed internally and must not be used for customer update prompts.
|
|
13
13
|
- Launcher update checks may call the CodexAPI.pro version endpoint and `@codexapi/codexclaude` npm metadata only.
|
|
14
14
|
- The launcher must never check `@openai/codex` npm metadata or OpenAI GitHub releases for update notices.
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
- Passes unknown commands directly to the bundled runtime after config is applied.
|
|
26
26
|
- Provides `codexclaude changelog` using the managed version endpoint.
|
|
27
27
|
- Does not expose separate `codexclaude status` or `codexclaude usage` commands; wallet information remains a compact pre-launch line.
|
|
28
|
-
-
|
|
29
|
-
- Mandatory updates present a press-Enter `Upgrade Now` action
|
|
28
|
+
- The backend minimum controls enforcement. Never require an unpublished or unverified archive.
|
|
29
|
+
- Mandatory updates present a press-Enter `Upgrade Now` action, install the exact managed version through npm-cli.js on Windows, verify npm's actual global package, fall back to a checksum-verified local archive and relaunch its verified entrypoint through Node. Do not weaken npm policies or rely on stale PATH aliases.
|
|
30
30
|
- The npm package manifest exposes only `codexclaude`, preventing npm from colliding with a native `codex` or `claude` command before postinstall runs.
|
|
31
31
|
- Global installation creates optional `codex` and `claude` aliases only when no existing command is present in the npm prefix or anywhere on `PATH`; native clients must never be overwritten.
|
|
32
32
|
- `codexclaude topup` and `codexclaude /topup` authenticate with the saved System Token, map the six fixed packages to the correct site-specific plan ids, and call only `/api/v1/wallet/stripe/checkout` and `/api/v1/wallet/stripe/confirm`.
|
|
@@ -48,7 +48,7 @@ The launcher writes a model provider named `codexapi`:
|
|
|
48
48
|
## Runtime Defaults
|
|
49
49
|
|
|
50
50
|
- Default model: `gpt-5.6-sol` displayed as `GPT-5.6 SOL`
|
|
51
|
-
-
|
|
51
|
+
- Picker order: `gpt-6-astra`, `claude-fable-5` (Fable 5.1), `claude-opus-5`, followed by current GPT-5.6, Daybreak and Sonnet variants. GPT-5.5 and Opus 4.8 are hidden compatibility entries, not deleted API identities. Numeric choices are derived from visible order, never stored as stale aliases.
|
|
52
52
|
- Default reasoning effort displayed locally: `Extra High`, stored as `xhigh`; SOL Max and SOL Ultra retain their explicit premium labels.
|
|
53
53
|
- Reasoning hint written to managed runtime config: model-specific
|
|
54
54
|
- Approval policy: `never`
|
|
@@ -67,10 +67,12 @@ Before launching the runtime, the launcher calls `/api/v1/wallet/status`, then `
|
|
|
67
67
|
Expected status line:
|
|
68
68
|
|
|
69
69
|
```text
|
|
70
|
-
MagnetAPI.org Codex CLI v2.0.
|
|
71
|
-
Fable 5 is now available in codexclaude
|
|
70
|
+
MagnetAPI.org Codex CLI v2.0.39 · GPT-5.6 SOL Extra High · ~/project · Wallet balance $20.00
|
|
71
|
+
Fable 5.1 is now available in codexclaude.
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
`bin/splash.js` owns the terminal-only binary graphic and launch classification. Preserve `codexclaude, powered by https://magnetapi.org`, own app version, responsive widths, NO_COLOR, TERM=dumb and explicit opt-outs. No sleeps, clearing, network calls or decorations in headless/JSON/server output. `test/frontier.test.js` checks ordering, legacy visibility, numeric selection and splash behavior. `test/update.test.js` covers local verified fallback and Windows npm resolution.
|
|
75
|
+
|
|
74
76
|
## Upgrade Checklist
|
|
75
77
|
|
|
76
78
|
When updating the bundled runtime:
|
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# codexclaude
|
|
2
2
|
|
|
3
|
-
`codexclaude` installs the MagnetAPI.org Codex CLI for customers who want one coding
|
|
3
|
+
`codexclaude` installs the MagnetAPI.org Codex CLI for customers who want one coding client for ChatGPT-6-Astra, Fable 5.1, Opus 5, Sonnet 5, Daybreak Blue and GPT-5.6 models, using the same Token Wallet.
|
|
4
4
|
|
|
5
|
-
Version `2.0.
|
|
5
|
+
Version `2.0.39` bundles the exact Codex runtime dependency `@openai/codex@0.154.0`. The model picker starts with ChatGPT-6-Astra, Fable 5.1 and Opus 5. GPT-5.6 SOL with Extra High reasoning remains the default; existing valid selections are preserved. The release retains four-site authentication, wallet integration, Full Access defaults, local tools, safe configuration merging and managed updates.
|
|
6
6
|
|
|
7
7
|
## Install Or Update
|
|
8
8
|
|
|
@@ -16,7 +16,7 @@ This does not delete local session history. The update replaces the `codexclaude
|
|
|
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
|
-
|
|
19
|
+
The service's release metadata determines the minimum supported version. When an update is required, pressing Enter at `Upgrade Now` installs the exact managed release and restarts the requested action. If npm is unavailable or stale, this release downloads and verifies the hosted package before installing it as a local file. Native `codex` and `claude` commands are never overwritten. Non-interactive commands fail clearly rather than waiting for input.
|
|
20
20
|
|
|
21
21
|
## First Login
|
|
22
22
|
|
|
@@ -44,7 +44,7 @@ Switch model:
|
|
|
44
44
|
codexclaude model
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
The first three choices are `ChatGPT-6-Astra`, `Fable 5.1` and `Opus 5`, followed by GPT-5.6, Daybreak Blue, SOL Max, SOL Ultra, SOL, Sonnet 5 and Terra. `codexclaude model`, `models`, `/model` and `/models` open the same launcher selector; the native in-session command remains `/model`. Legacy GPT-5.5 and Opus 4.8 metadata is hidden from new selection but retained for existing configurations. Fable 5.1 uses the compatible API id `claude-fable-5`; billing remains server-managed.
|
|
48
48
|
|
|
49
49
|
## Launch Commands
|
|
50
50
|
|
|
@@ -80,14 +80,17 @@ Card numbers, CVCs, and bank authentication challenges are entered only on Strip
|
|
|
80
80
|
Before launching the coding runtime, the app prints a compact status line like:
|
|
81
81
|
|
|
82
82
|
```text
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
codexclaude, powered by https://magnetapi.org
|
|
84
|
+
MagnetAPI.org Codex CLI v2.0.39 · GPT-5.6 SOL Extra High · ~/project · Wallet balance $20.00
|
|
85
|
+
Fable 5.1 is now available in codexclaude.
|
|
85
86
|
```
|
|
86
87
|
|
|
88
|
+
Interactive startup includes a gold-and-cyan binary graphic. Narrow terminals use a compact design. `NO_COLOR` and `TERM=dumb` disable color; `CODEXCLAUDE_NO_SPLASH=1` hides the graphic, and `CODEXCLAUDE_QUIET_STATUS=1` hides all launcher startup decoration. Exec/JSON, completion, server protocols, pipes and version/help output never receive splash or wallet text.
|
|
89
|
+
|
|
87
90
|
## Preserved Customizations
|
|
88
91
|
|
|
89
92
|
- Dashboard Username or Email Address plus password login for CodexAPI.pro, ChatPlus.chat, MyAPI.world, and MagnetAPI.org.
|
|
90
|
-
-
|
|
93
|
+
- Frontier-first model selection, with GPT-5.6 SOL/Extra High as the default and legacy configuration compatibility.
|
|
91
94
|
- Service-specific Responses-compatible provider for the dashboard account that logged in.
|
|
92
95
|
- Full Access defaults: approval policy `never` and sandbox mode `danger-full-access`.
|
|
93
96
|
- Model-specific visible reasoning in the local UI while the API server keeps upstream runtime effort server-managed.
|
package/bin/codexclaude.js
CHANGED
|
@@ -2,18 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
import { spawn, spawnSync } from "node:child_process";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, chmodSync, unlinkSync } from "node:fs";
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, chmodSync, unlinkSync, renameSync } from "node:fs";
|
|
6
|
+
import TOML from "@iarna/toml";
|
|
6
7
|
import { homedir } from "node:os";
|
|
7
8
|
import path from "node:path";
|
|
8
9
|
import readline from "node:readline/promises";
|
|
9
10
|
import { stdin as input, stdout as output } from "node:process";
|
|
10
11
|
import { fileURLToPath } from "node:url";
|
|
11
12
|
import { installSafeCommandAliases } from "../scripts/install-safe-aliases.js";
|
|
13
|
+
import { renderSplash, isInteractiveLaunch } from "./splash.js";
|
|
14
|
+
import { installedPackage, npmInvocation, performUpdate, releaseTarget } from "./update.js";
|
|
12
15
|
|
|
13
16
|
const require = createRequire(import.meta.url);
|
|
14
17
|
|
|
15
|
-
const APP_VERSION = "2.0.
|
|
16
|
-
const CODEX_VERSION = "0.
|
|
18
|
+
const APP_VERSION = "2.0.39";
|
|
19
|
+
const CODEX_VERSION = "0.154.0";
|
|
17
20
|
const APP_DISPLAY_NAME = "MagnetAPI.org Codex CLI";
|
|
18
21
|
const DEFAULT_MODEL_ID = "gpt-5.6-sol";
|
|
19
22
|
const DEFAULT_DISPLAY_REASONING_EFFORT = "xhigh";
|
|
@@ -36,7 +39,7 @@ const CODEX_CONFIG_FILE = path.join(CODEX_DIR, "config.toml");
|
|
|
36
39
|
const CODEX_UPDATE_CACHE_FILE = path.join(CODEX_DIR, "version.json");
|
|
37
40
|
const PROVIDER_ID = "codexapi";
|
|
38
41
|
const MODEL_CATALOG_CONTEXT_WINDOW = 272000;
|
|
39
|
-
const FABLE_ANNOUNCEMENT = "Fable 5 is now available in codexclaude
|
|
42
|
+
const FABLE_ANNOUNCEMENT = "Fable 5.1 is now available in codexclaude.";
|
|
40
43
|
const ANSI_GREEN = "\x1b[32m";
|
|
41
44
|
const ANSI_RESET = "\x1b[0m";
|
|
42
45
|
const SERVICE_CATALOG = [
|
|
@@ -91,80 +94,84 @@ const TOPUP_POLL_INTERVAL_MS = positiveInteger(process.env.CODEXCLAUDE_TOPUP_POL
|
|
|
91
94
|
const TOPUP_TIMEOUT_MS = positiveInteger(process.env.CODEXCLAUDE_TOPUP_TIMEOUT_MS, 30 * 60 * 1000);
|
|
92
95
|
|
|
93
96
|
const MODELS = {
|
|
97
|
+
"gpt-6-astra": {
|
|
98
|
+
id: "gpt-6-astra",
|
|
99
|
+
label: "ChatGPT-6-Astra",
|
|
100
|
+
aliases: ["astra", "gpt-6", "gpt-6-astra", "gpt6-astra", "chatgpt-6-astra"],
|
|
101
|
+
reasoningEffort: "xhigh",
|
|
102
|
+
contextWindow: 1050000,
|
|
103
|
+
maxOutputTokens: 128000,
|
|
104
|
+
premium: true,
|
|
105
|
+
supportedReasoningLevels: SUPPORTED_REASONING_LEVELS.filter(({ effort }) => effort !== "ultra"),
|
|
106
|
+
},
|
|
107
|
+
"claude-fable-5": {
|
|
108
|
+
id: "claude-fable-5",
|
|
109
|
+
label: "Fable 5.1",
|
|
110
|
+
aliases: ["fable", "fable-5.1", "claude-fable-5.1", "fable-5", "fabel", "fabel-5", "claude-fable-5", "claude-fabel-5"],
|
|
111
|
+
premium: true,
|
|
112
|
+
},
|
|
94
113
|
"claude-opus-5": {
|
|
95
114
|
id: "claude-opus-5",
|
|
96
115
|
label: "Opus 5",
|
|
97
|
-
aliases: ["
|
|
116
|
+
aliases: ["opus", "opus-5", "claude", "claude-opus-5"],
|
|
98
117
|
},
|
|
99
118
|
"gpt-5.6": {
|
|
100
119
|
id: "gpt-5.6",
|
|
101
120
|
label: "GPT-5.6",
|
|
102
|
-
aliases: ["
|
|
121
|
+
aliases: ["gpt", "gpt-5.6", "chatgpt", "chatgpt-5.6", "gpt56"],
|
|
103
122
|
reasoningEffort: "xhigh",
|
|
104
123
|
},
|
|
105
124
|
"gpt-daybreak-blue-latest": {
|
|
106
125
|
id: "gpt-daybreak-blue-latest",
|
|
107
126
|
label: "ChatGPT Daybreak Blue",
|
|
108
|
-
aliases: ["
|
|
127
|
+
aliases: ["daybreak", "daybreak-blue", "chatgpt-daybreak-blue", "gpt-daybreak-blue-latest"],
|
|
109
128
|
reasoningEffort: "xhigh",
|
|
110
129
|
},
|
|
111
130
|
"gpt-5.6-sol-max": {
|
|
112
131
|
id: "gpt-5.6-sol-max",
|
|
113
132
|
label: "GPT-5.6 SOL Max",
|
|
114
|
-
aliases: ["
|
|
133
|
+
aliases: ["gpt-5.6-sol-max", "gpt-5.6-max", "gpt56-max", "sol-max", "max"],
|
|
115
134
|
reasoningEffort: "max",
|
|
116
135
|
},
|
|
117
136
|
"gpt-5.6-sol-ultra": {
|
|
118
137
|
id: "gpt-5.6-sol-ultra",
|
|
119
138
|
label: "GPT-5.6 SOL Ultra",
|
|
120
|
-
aliases: ["
|
|
139
|
+
aliases: ["gpt-5.6-sol-ultra", "gpt-5.6-ultra", "gpt56-ultra", "sol-ultra", "ultra"],
|
|
121
140
|
reasoningEffort: "ultra",
|
|
122
141
|
},
|
|
123
142
|
"gpt-5.6-sol": {
|
|
124
143
|
id: "gpt-5.6-sol",
|
|
125
144
|
label: "GPT-5.6 SOL",
|
|
126
|
-
aliases: ["
|
|
145
|
+
aliases: ["gpt-5.6-sol", "sol"],
|
|
127
146
|
reasoningEffort: "xhigh",
|
|
128
147
|
},
|
|
129
148
|
"gpt-5.5": {
|
|
130
149
|
id: "gpt-5.5",
|
|
131
150
|
label: "ChatGPT-5.5",
|
|
132
|
-
aliases: ["
|
|
151
|
+
aliases: ["gpt-5.5", "chatgpt-5.5"],
|
|
152
|
+
legacy: true,
|
|
133
153
|
},
|
|
134
154
|
"claude-opus-4-8": {
|
|
135
155
|
id: "claude-opus-4-8",
|
|
136
156
|
label: "Opus 4.8",
|
|
137
|
-
aliases: ["
|
|
157
|
+
aliases: ["opus-4.8", "opus-4.7", "claude-opus-4-8", "claude-opus-4-7"],
|
|
158
|
+
legacy: true,
|
|
138
159
|
},
|
|
139
160
|
"claude-sonnet-5": {
|
|
140
161
|
id: "claude-sonnet-5",
|
|
141
162
|
label: "Sonnet 5",
|
|
142
|
-
aliases: ["
|
|
143
|
-
},
|
|
144
|
-
"claude-fable-5": {
|
|
145
|
-
id: "claude-fable-5",
|
|
146
|
-
label: "Fable 5",
|
|
147
|
-
aliases: ["10", "fable", "fable-5", "fabel", "fabel-5", "claude-fable-5", "claude-fabel-5"],
|
|
148
|
-
premium: true,
|
|
163
|
+
aliases: ["sonnet", "sonnet-5", "sonnet-4.6", "sonnet-4-6", "claude-sonnet-5", "claude-sonnet-4-6", "claude-sonnet-4.6"],
|
|
149
164
|
},
|
|
150
165
|
"gpt-5.6-terra": {
|
|
151
166
|
id: "gpt-5.6-terra",
|
|
152
167
|
label: "GPT-5.6 Terra",
|
|
153
|
-
aliases: ["
|
|
168
|
+
aliases: ["terra", "gpt-5.6-terra", "gpt56-terra"],
|
|
154
169
|
reasoningEffort: "xhigh",
|
|
155
170
|
},
|
|
156
|
-
"gpt-6-astra": {
|
|
157
|
-
id: "gpt-6-astra",
|
|
158
|
-
label: "ChatGPT-6 Astra",
|
|
159
|
-
aliases: ["12", "astra", "gpt-6", "gpt-6-astra", "gpt6-astra", "chatgpt-6-astra"],
|
|
160
|
-
reasoningEffort: "xhigh",
|
|
161
|
-
contextWindow: 1050000,
|
|
162
|
-
maxOutputTokens: 128000,
|
|
163
|
-
premium: true,
|
|
164
|
-
supportedReasoningLevels: SUPPORTED_REASONING_LEVELS.filter(({ effort }) => effort !== "ultra"),
|
|
165
|
-
},
|
|
166
171
|
};
|
|
167
172
|
|
|
173
|
+
const PICKER_MODELS = Object.values(MODELS).filter((model) => !model.legacy);
|
|
174
|
+
|
|
168
175
|
async function main() {
|
|
169
176
|
ensureExecutable();
|
|
170
177
|
ensureSafeCommandAliases();
|
|
@@ -192,7 +199,7 @@ async function main() {
|
|
|
192
199
|
logout();
|
|
193
200
|
return;
|
|
194
201
|
}
|
|
195
|
-
if (
|
|
202
|
+
if (["model", "models", "/model", "/models"].includes(command)) {
|
|
196
203
|
await modelFlow();
|
|
197
204
|
return;
|
|
198
205
|
}
|
|
@@ -226,7 +233,7 @@ ${APP_DISPLAY_NAME} v${APP_VERSION}
|
|
|
226
233
|
|
|
227
234
|
Commands:
|
|
228
235
|
codexclaude login Login with dashboard username/email and password
|
|
229
|
-
codexclaude
|
|
236
|
+
codexclaude models Select ChatGPT-6-Astra, Fable 5.1, Opus 5, or another current model
|
|
230
237
|
codexclaude changelog Show the latest CodexAPI.pro launcher changes
|
|
231
238
|
codexclaude setup Rewrite ~/.codex/config.toml with Full Access defaults
|
|
232
239
|
codexclaude topup Select an API Coding Credit package and securely complete payment
|
|
@@ -564,7 +571,7 @@ async function ensureReady() {
|
|
|
564
571
|
async function askModel(rl, current) {
|
|
565
572
|
const currentLabel = MODELS[current]?.label || MODELS[DEFAULT_MODEL_ID].label;
|
|
566
573
|
console.log("\nChoose your coding model:");
|
|
567
|
-
|
|
574
|
+
PICKER_MODELS.forEach((model, index) => {
|
|
568
575
|
console.log(` ${index + 1}. ${model.label}`);
|
|
569
576
|
});
|
|
570
577
|
const answer = (await rl.question(`Model [${currentLabel}]: `)).trim().toLowerCase();
|
|
@@ -573,7 +580,7 @@ async function askModel(rl, current) {
|
|
|
573
580
|
printModelSelectionWarning(selected);
|
|
574
581
|
return selected;
|
|
575
582
|
}
|
|
576
|
-
const match =
|
|
583
|
+
const match = PICKER_MODELS.find((model, index) => String(index + 1) === answer || model.aliases.includes(answer));
|
|
577
584
|
if (!match) {
|
|
578
585
|
throw new Error("Unknown model choice. Run codexclaude model and choose one of the numbered options.");
|
|
579
586
|
}
|
|
@@ -641,7 +648,6 @@ async function enforceLauncherVersion() {
|
|
|
641
648
|
async function runMandatoryUpgrade(metadata) {
|
|
642
649
|
const latest = metadata?.latestVersion || "latest";
|
|
643
650
|
const minimum = metadata?.minimumVersion || latest;
|
|
644
|
-
const hostedTarballUrl = metadata?.hostedTarballUrl || HOSTED_TARBALL_URL;
|
|
645
651
|
const changes = Array.isArray(metadata?.changes) ? metadata.changes.slice(0, 4) : [];
|
|
646
652
|
console.error(`\n✨ Update now available · ${APP_DISPLAY_NAME} v${latest}`);
|
|
647
653
|
console.error(`${APP_DISPLAY_NAME} v${latest} is required before your next coding session.`);
|
|
@@ -671,28 +677,21 @@ async function runMandatoryUpgrade(metadata) {
|
|
|
671
677
|
}
|
|
672
678
|
|
|
673
679
|
console.log(`\nDownloading and installing ${NPM_PACKAGE_NAME}@latest...`);
|
|
674
|
-
const
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
if (exitCode !== 0 || isOlderVersion(installedVersion, minimum)) {
|
|
686
|
-
throw new Error(
|
|
687
|
-
`Automatic upgrade failed with exit code ${exitCode} and installed version ${installedVersion || "unknown"}. Run ${UPDATE_COMMAND}. ` +
|
|
688
|
-
`If npm is unavailable, use: npm install -g ${hostedTarballUrl}`,
|
|
689
|
-
);
|
|
690
|
-
}
|
|
680
|
+
const npm = npmInvocation();
|
|
681
|
+
const installed = await performUpdate({
|
|
682
|
+
release: releaseTarget(metadata, null),
|
|
683
|
+
runNpm: args => spawnAndWait(npm.command, [...npm.args, ...args]),
|
|
684
|
+
readInstalled: () => {
|
|
685
|
+
const result = spawnSync(npm.command, [...npm.args, "root", "-g"], {
|
|
686
|
+
encoding: "utf8", timeout: 30000, shell: false,
|
|
687
|
+
});
|
|
688
|
+
return result.status === 0 ? installedPackage(String(result.stdout || "")) : null;
|
|
689
|
+
},
|
|
690
|
+
});
|
|
691
691
|
console.log(`\nUpgrade complete. Restarting ${APP_DISPLAY_NAME} now...`);
|
|
692
692
|
const relaunchArgs = process.argv.slice(2);
|
|
693
|
-
const relaunchCommand = process.platform === "win32" ? "codexclaude.cmd" : "codexclaude";
|
|
694
693
|
try {
|
|
695
|
-
const relaunchExitCode = await spawnAndWait(
|
|
694
|
+
const relaunchExitCode = await spawnAndWait(process.execPath, [installed.entrypoint, ...relaunchArgs]);
|
|
696
695
|
if (relaunchExitCode !== 0) {
|
|
697
696
|
throw new Error(`updated client exited with code ${relaunchExitCode}`);
|
|
698
697
|
}
|
|
@@ -704,24 +703,6 @@ async function runMandatoryUpgrade(metadata) {
|
|
|
704
703
|
}
|
|
705
704
|
}
|
|
706
705
|
|
|
707
|
-
function installedLauncherVersion() {
|
|
708
|
-
const command = process.platform === "win32" ? "codexclaude.cmd" : "codexclaude";
|
|
709
|
-
const result = spawnSync(command, ["--version"], {
|
|
710
|
-
encoding: "utf8",
|
|
711
|
-
env: {
|
|
712
|
-
...process.env,
|
|
713
|
-
CODEXCLAUDE_DISABLE_UPDATE_CHECK: "1",
|
|
714
|
-
CODEXCLAUDE_SKIP_COMMAND_ALIASES: "1",
|
|
715
|
-
},
|
|
716
|
-
shell: false,
|
|
717
|
-
});
|
|
718
|
-
if (result.error || result.status !== 0) {
|
|
719
|
-
return null;
|
|
720
|
-
}
|
|
721
|
-
const match = String(result.stdout || "").match(/\bv(\d+(?:\.\d+){2})\b/i);
|
|
722
|
-
return match?.[1] || null;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
706
|
async function spawnAndWait(command, args) {
|
|
726
707
|
return await new Promise((resolve, reject) => {
|
|
727
708
|
const child = spawn(command, args, { stdio: "inherit", env: process.env, shell: false });
|
|
@@ -945,6 +926,8 @@ function isTruthy(value) {
|
|
|
945
926
|
|
|
946
927
|
function writeCodexConfig(config) {
|
|
947
928
|
mkdirSync(CODEX_DIR, { recursive: true });
|
|
929
|
+
const existing = existsSync(CODEX_CONFIG_FILE)
|
|
930
|
+
? TOML.parse(readFileSync(CODEX_CONFIG_FILE, "utf8").replace(/^\uFEFF/, "")) : {};
|
|
948
931
|
if (existsSync(CODEX_CONFIG_FILE)) {
|
|
949
932
|
const backup = `${CODEX_CONFIG_FILE}.backup.${timestamp()}`;
|
|
950
933
|
copyFileSync(CODEX_CONFIG_FILE, backup);
|
|
@@ -981,7 +964,16 @@ function writeCodexConfig(config) {
|
|
|
981
964
|
'terminal_title = ["project-name", "model-with-reasoning", "run-state"]',
|
|
982
965
|
"",
|
|
983
966
|
].join("\n");
|
|
984
|
-
|
|
967
|
+
const managed = TOML.parse(toml);
|
|
968
|
+
const merged = {
|
|
969
|
+
...existing,
|
|
970
|
+
...managed,
|
|
971
|
+
model_providers: { ...existing.model_providers, ...managed.model_providers },
|
|
972
|
+
tui: { ...existing.tui, ...managed.tui },
|
|
973
|
+
};
|
|
974
|
+
const temporary = `${CODEX_CONFIG_FILE}.tmp.${process.pid}`;
|
|
975
|
+
writeFileSync(temporary, TOML.stringify(merged), { encoding: "utf8", mode: 0o600 });
|
|
976
|
+
renameSync(temporary, CODEX_CONFIG_FILE);
|
|
985
977
|
}
|
|
986
978
|
|
|
987
979
|
function clearUpstreamUpdateCache() {
|
|
@@ -997,7 +989,8 @@ function clearUpstreamUpdateCache() {
|
|
|
997
989
|
function writeModelCatalog() {
|
|
998
990
|
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
999
991
|
const catalog = {
|
|
1000
|
-
models: Object.values(MODELS).
|
|
992
|
+
models: [...PICKER_MODELS, ...Object.values(MODELS).filter((model) => model.legacy)]
|
|
993
|
+
.map((model, index) => modelCatalogEntry(model, index)),
|
|
1001
994
|
};
|
|
1002
995
|
writeFileSync(MODEL_CATALOG_FILE, `${JSON.stringify(catalog, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
|
|
1003
996
|
return MODEL_CATALOG_FILE;
|
|
@@ -1026,7 +1019,7 @@ function modelCatalogEntry(model, index) {
|
|
|
1026
1019
|
default_reasoning_level: reasoningEffortForModel(model.id),
|
|
1027
1020
|
supported_reasoning_levels: model.supportedReasoningLevels || SUPPORTED_REASONING_LEVELS,
|
|
1028
1021
|
shell_type: "shell_command",
|
|
1029
|
-
visibility: "list",
|
|
1022
|
+
visibility: model.legacy ? "hide" : "list",
|
|
1030
1023
|
minimal_client_version: "0.124.0",
|
|
1031
1024
|
supported_in_api: true,
|
|
1032
1025
|
availability_nux: null,
|
|
@@ -1044,7 +1037,7 @@ function modelCatalogEntry(model, index) {
|
|
|
1044
1037
|
|
|
1045
1038
|
function modelCatalogDescription(modelId) {
|
|
1046
1039
|
if (modelId === "gpt-6-astra") {
|
|
1047
|
-
return "ChatGPT-6
|
|
1040
|
+
return "ChatGPT-6-Astra: coding tools, configurable reasoning, and image input.";
|
|
1048
1041
|
}
|
|
1049
1042
|
if (modelId === "gpt-5.6") {
|
|
1050
1043
|
return "GPT-5.6 coding route with local coding tools and wallet billing.";
|
|
@@ -1074,7 +1067,7 @@ function modelCatalogDescription(modelId) {
|
|
|
1074
1067
|
return "Sonnet 5 coding route with local coding tools and wallet billing.";
|
|
1075
1068
|
}
|
|
1076
1069
|
if (modelId === "claude-fable-5") {
|
|
1077
|
-
return "Fable 5
|
|
1070
|
+
return "Fable 5.1: coding tools and image input, using the compatible Fable 5 API id.";
|
|
1078
1071
|
}
|
|
1079
1072
|
return "ChatGPT-5.5 coding route with local coding tools and wallet billing.";
|
|
1080
1073
|
}
|
|
@@ -1107,17 +1100,28 @@ function logout() {
|
|
|
1107
1100
|
|
|
1108
1101
|
async function runCodex(args) {
|
|
1109
1102
|
const config = requireConfig();
|
|
1103
|
+
const interactive = isInteractiveLaunch(args, {
|
|
1104
|
+
stdinTTY: input.isTTY, stdoutTTY: output.isTTY,
|
|
1105
|
+
quiet: isTruthy(process.env.CODEXCLAUDE_QUIET_STATUS),
|
|
1106
|
+
});
|
|
1107
|
+
if (interactive && !isTruthy(process.env.CODEXCLAUDE_NO_SPLASH)) {
|
|
1108
|
+
process.stderr.write(renderSplash({
|
|
1109
|
+
version: APP_VERSION, columns: output.columns,
|
|
1110
|
+
color: process.env.NO_COLOR === undefined && process.env.TERM !== "dumb",
|
|
1111
|
+
}));
|
|
1112
|
+
}
|
|
1110
1113
|
let wallet = null;
|
|
1111
1114
|
try {
|
|
1112
1115
|
wallet = await walletSnapshot(config);
|
|
1113
1116
|
} catch {
|
|
1114
1117
|
// Wallet lookup should never block the user from starting a local coding session.
|
|
1115
1118
|
}
|
|
1116
|
-
if (
|
|
1119
|
+
if (interactive) {
|
|
1117
1120
|
console.log(formatStatusLine(config, wallet, process.cwd()));
|
|
1118
|
-
|
|
1121
|
+
const color = process.env.NO_COLOR === undefined && process.env.TERM !== "dumb";
|
|
1122
|
+
console.log(color ? `${ANSI_GREEN}${FABLE_ANNOUNCEMENT}${ANSI_RESET}` : FABLE_ANNOUNCEMENT);
|
|
1123
|
+
if (color) process.stdout.write(`\x1b]0;${APP_DISPLAY_NAME} v${APP_VERSION}\x07`);
|
|
1119
1124
|
}
|
|
1120
|
-
process.stdout.write(`\x1b]0;${APP_DISPLAY_NAME} v${APP_VERSION}\x07`);
|
|
1121
1125
|
const launch = resolveCodexLaunch();
|
|
1122
1126
|
const env = {
|
|
1123
1127
|
...process.env,
|
|
@@ -1350,7 +1354,7 @@ function normalizeConfig(config) {
|
|
|
1350
1354
|
if (["claude-sonnet-4.6", "claude-sonnet-4-6", "sonnet-4.6", "sonnet-4-6", "sonnet-5"].includes(normalized.model)) {
|
|
1351
1355
|
normalized.model = "claude-sonnet-5";
|
|
1352
1356
|
}
|
|
1353
|
-
if (["claude-fabel-5", "fable-5", "fabel-5"].includes(normalized.model)) {
|
|
1357
|
+
if (["claude-fabel-5", "fable-5", "fabel-5", "fable-5.1", "claude-fable-5.1"].includes(normalized.model)) {
|
|
1354
1358
|
normalized.model = "claude-fable-5";
|
|
1355
1359
|
}
|
|
1356
1360
|
if (["gpt-5.6-sol-max", "gpt-5.6-max", "gpt56-max", "sol-max", "max"].includes(normalized.model)) {
|
package/bin/splash.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Terminal-only artwork. Never delay startup or mix it into machine-readable output.
|
|
2
|
+
export function isInteractiveLaunch(args, { stdinTTY, stdoutTTY, quiet = false }) {
|
|
3
|
+
if (!stdinTTY || !stdoutTTY || quiet) return false;
|
|
4
|
+
if (args.some((arg) => /^(?:--json(?:=|$)|--help$|-h$|--version$|-V$)/.test(arg))) return false;
|
|
5
|
+
return !["exec", "e", "review", "app-server", "mcp-server", "completion", "mcp", "debug", "features"].includes(args[0]);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function renderSplash({ version, columns = 80, color = true }) {
|
|
9
|
+
const width = Math.max(1, Math.min(Number(columns) || 80, 74));
|
|
10
|
+
const gold = color ? "\x1b[93m" : "";
|
|
11
|
+
const cyan = color ? "\x1b[36m" : "";
|
|
12
|
+
const bold = color ? "\x1b[1m" : "";
|
|
13
|
+
const reset = color ? "\x1b[0m" : "";
|
|
14
|
+
const lines = [];
|
|
15
|
+
const add = (value, style = "") => {
|
|
16
|
+
for (let offset = 0; offset < value.length; offset += width) {
|
|
17
|
+
lines.push(style + value.slice(offset, offset + width) + reset);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
add("-".repeat(width), cyan);
|
|
21
|
+
if (width >= 40) {
|
|
22
|
+
[
|
|
23
|
+
" 011110 011110 010 101 001",
|
|
24
|
+
" 01 01 101 010 110",
|
|
25
|
+
" 10 10 010 101 001",
|
|
26
|
+
" 01 01 101 010 110",
|
|
27
|
+
" 100111 100111 010 101 001",
|
|
28
|
+
].forEach((line) => add(line, gold));
|
|
29
|
+
} else {
|
|
30
|
+
add("0101 CODE + CREATE 1010", gold);
|
|
31
|
+
}
|
|
32
|
+
add(`codexclaude v${version}`, bold + gold);
|
|
33
|
+
add("codexclaude, powered by https://magnetapi.org", cyan);
|
|
34
|
+
add("-".repeat(width), cyan);
|
|
35
|
+
return "\n" + lines.join("\n") + "\n\n";
|
|
36
|
+
}
|
package/bin/update.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { mkdtemp, writeFile, rm } from "node:fs/promises";
|
|
3
|
+
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
|
|
7
|
+
export const PACKAGE = "@codexapi/codexclaude";
|
|
8
|
+
const VERSION = /^\d+\.\d+\.\d+$/;
|
|
9
|
+
|
|
10
|
+
export function atLeast(actual, required) {
|
|
11
|
+
if (!VERSION.test(actual || "") || !VERSION.test(required || "")) return false;
|
|
12
|
+
const a = actual.split(".").map(Number), b = required.split(".").map(Number);
|
|
13
|
+
for (let i = 0; i < 3; i++) if (a[i] !== b[i]) return a[i] > b[i];
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function releaseTarget(service, registry) {
|
|
18
|
+
const versions = [service?.latestVersion, service?.minimumVersion, registry?.version].filter(v => VERSION.test(v || ""));
|
|
19
|
+
const version = versions.reduce((a, b) => atLeast(a, b) ? a : b, null);
|
|
20
|
+
if (!version) throw new Error("No valid managed release version is available. Please retry shortly.");
|
|
21
|
+
const hostedTarballUrl = `https://codexapi.pro/downloads/codexapi-codexclaude-${version}.tgz`;
|
|
22
|
+
return { version, hostedTarballUrl, sha256: service?.latestVersion === version ? service.hostedTarballSha256 : null };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function downloadVerified(release, fetchImpl = fetch) {
|
|
26
|
+
const expectedUrl = `https://codexapi.pro/downloads/codexapi-codexclaude-${release.version}.tgz`;
|
|
27
|
+
if (!VERSION.test(release.version) || release.hostedTarballUrl !== expectedUrl) throw new Error("Untrusted managed update location.");
|
|
28
|
+
const request = async url => {
|
|
29
|
+
const response = await fetchImpl(url, { redirect: "error", signal: AbortSignal.timeout(60000) });
|
|
30
|
+
if (!response.ok) throw new Error(`Managed update download failed (HTTP ${response.status}).`);
|
|
31
|
+
return response;
|
|
32
|
+
};
|
|
33
|
+
const hash = release.sha256 || (await (await request(`${expectedUrl}.sha256`)).text()).trim().split(/\s+/)[0];
|
|
34
|
+
if (!/^[a-f0-9]{64}$/i.test(hash || "")) throw new Error("Managed update checksum is unavailable. No package was installed.");
|
|
35
|
+
const response = await request(expectedUrl);
|
|
36
|
+
const chunks = [];
|
|
37
|
+
let size = 0;
|
|
38
|
+
for await (const chunk of response.body) {
|
|
39
|
+
size += chunk.length;
|
|
40
|
+
if (size > 25 * 1024 * 1024) throw new Error("Managed update exceeds the download size limit.");
|
|
41
|
+
chunks.push(chunk);
|
|
42
|
+
}
|
|
43
|
+
const contents = Buffer.concat(chunks);
|
|
44
|
+
if (createHash("sha256").update(contents).digest("hex") !== hash.toLowerCase()) throw new Error("Managed update checksum mismatch. No package was installed.");
|
|
45
|
+
const directory = await mkdtemp(path.join(tmpdir(), "codexclaude-update-"));
|
|
46
|
+
const file = path.join(directory, `codexclaude-${release.version}.tgz`);
|
|
47
|
+
try { await writeFile(file, contents, { mode: 0o600, flag: "wx" }); }
|
|
48
|
+
catch (error) { await rm(directory, { recursive: true, force: true }); throw error; }
|
|
49
|
+
return { file, cleanup: () => rm(directory, { recursive: true, force: true }) };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function npmInvocation(env = process.env, platform = process.platform, executable = process.execPath) {
|
|
53
|
+
const candidates = [env.npm_execpath, path.join(path.dirname(executable), "node_modules/npm/bin/npm-cli.js")].filter(Boolean);
|
|
54
|
+
if (platform === "win32" && env.APPDATA) candidates.push(path.join(env.APPDATA, "npm/node_modules/npm/bin/npm-cli.js"));
|
|
55
|
+
for (const directory of (env.PATH || env.Path || "").split(platform === "win32" ? ";" : ":")) {
|
|
56
|
+
if (!directory) continue;
|
|
57
|
+
candidates.push(path.join(directory, "node_modules/npm/bin/npm-cli.js"));
|
|
58
|
+
if (platform !== "win32") candidates.push(path.join(directory, "npm"));
|
|
59
|
+
}
|
|
60
|
+
for (const candidate of candidates) {
|
|
61
|
+
try {
|
|
62
|
+
const real = realpathSync(candidate);
|
|
63
|
+
if (path.basename(real) === "npm-cli.js") return { command: executable, args: [real] };
|
|
64
|
+
} catch {}
|
|
65
|
+
}
|
|
66
|
+
if (platform === "win32") throw new Error("npm could not be located. Repair your Node.js installation, then retry the update.");
|
|
67
|
+
return { command: "npm", args: [] };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function installedPackage(globalRoot) {
|
|
71
|
+
try {
|
|
72
|
+
const root = path.join(globalRoot.trim(), "@codexapi", "codexclaude");
|
|
73
|
+
const pkg = JSON.parse(readFileSync(path.join(root, "package.json"), "utf8"));
|
|
74
|
+
const entrypoint = path.join(root, "bin/codexclaude.js");
|
|
75
|
+
if (pkg.name !== PACKAGE || !VERSION.test(pkg.version) || !existsSync(entrypoint)) return null;
|
|
76
|
+
return { version: pkg.version, entrypoint };
|
|
77
|
+
} catch { return null; }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function performUpdate({ release, runNpm, readInstalled, download = downloadVerified }) {
|
|
81
|
+
let code = await runNpm(["install", "-g", `${PACKAGE}@${release.version}`]);
|
|
82
|
+
let installed = code === 0 ? await readInstalled() : null;
|
|
83
|
+
if (!installed || !atLeast(installed.version, release.version)) {
|
|
84
|
+
const artifact = await download(release);
|
|
85
|
+
try {
|
|
86
|
+
code = await runNpm(["install", "-g", artifact.file]);
|
|
87
|
+
installed = code === 0 ? await readInstalled() : null;
|
|
88
|
+
} finally { await artifact.cleanup(); }
|
|
89
|
+
}
|
|
90
|
+
if (code !== 0 || !installed || !atLeast(installed.version, release.version)) {
|
|
91
|
+
throw new Error(`Automatic update did not install v${release.version}. Run: npm install -g ${PACKAGE}@${release.version}`);
|
|
92
|
+
}
|
|
93
|
+
return installed;
|
|
94
|
+
}
|
package/codexclaude.md
CHANGED
|
@@ -4,6 +4,65 @@ This file is the durable handoff for the `@codexapi/codexclaude` package in `/ro
|
|
|
4
4
|
|
|
5
5
|
## Current Release
|
|
6
6
|
|
|
7
|
+
### 2026-09-10 Frontier Picker And Binary Splash: 2.0.39
|
|
8
|
+
|
|
9
|
+
This section supersedes older release snapshots below. Source/package version
|
|
10
|
+
is `2.0.39`, with exact `@openai/codex@0.154.0`. Release deployment state and npm
|
|
11
|
+
verification are recorded in `/root/codexapi/STATE.md`; never infer registry
|
|
12
|
+
publication or minimum enforcement from the source version alone.
|
|
13
|
+
|
|
14
|
+
The first three choices in the launcher selector and native catalog are
|
|
15
|
+
`ChatGPT-6-Astra` (`gpt-6-astra`), `Fable 5.1` (`claude-fable-5`) and `Opus 5`
|
|
16
|
+
(`claude-opus-5`). Remaining current choices retain their API ids. GPT-5.5 and
|
|
17
|
+
Opus 4.8 are compatibility-only: hidden from new selection, with full metadata
|
|
18
|
+
retained so upgrades do not change existing customer configurations or history.
|
|
19
|
+
Do not invent `claude-fable-5.1` upstream. A display alias normalizes to the stable
|
|
20
|
+
Fable id. Numeric choices are calculated from visible order to avoid selecting
|
|
21
|
+
the wrong model after reordering. `model`, `models`, `/model` and `/models` are
|
|
22
|
+
launcher aliases; the native interactive command remains `/model`.
|
|
23
|
+
|
|
24
|
+
Default model remains `gpt-5.6-sol`, Extra High. Full Access, four-site login,
|
|
25
|
+
customer wallet display, top-up, reasoning metadata, tool/image transport,
|
|
26
|
+
client headers and native-safe command aliases are preserved. Setup parses TOML,
|
|
27
|
+
backs up and atomically merges only owned fields. No runtime routing, billing,
|
|
28
|
+
provider credentials or regional native Codex installation is changed by this
|
|
29
|
+
launcher release.
|
|
30
|
+
|
|
31
|
+
`bin/splash.js` renders gold/cyan binary artwork and the exact line
|
|
32
|
+
`codexclaude, powered by https://magnetapi.org`, with app version 2.0.39.
|
|
33
|
+
It adapts to narrow terminals, has no animation delay and honors NO_COLOR,
|
|
34
|
+
TERM=dumb, CODEXCLAUDE_NO_SPLASH and CODEXCLAUDE_QUIET_STATUS. Launcher notices,
|
|
35
|
+
wallet text and terminal-title escapes are now excluded from exec/JSON, server
|
|
36
|
+
protocols, completions and pipes. Never pollute machine-readable stdout.
|
|
37
|
+
|
|
38
|
+
`bin/update.js` ports the tested claudecodex updater: exact registry target,
|
|
39
|
+
checksum-verified temporary local archive on fallback, bounded HTTPS downloads,
|
|
40
|
+
Windows npm-cli.js through Node, actual global package verification and direct
|
|
41
|
+
relaunch of that installed entrypoint. No npm --force/remote-policy override.
|
|
42
|
+
Only CodexAPI and our npm package may provide update metadata. Publish and verify
|
|
43
|
+
archives, SHA-256 sidecars, registry and dashboard scripts before raising the
|
|
44
|
+
minimum version. Preserve native binaries, local tools, providers and projects.
|
|
45
|
+
|
|
46
|
+
Run `npm test` for config preservation, frontier metadata, aliases, splash,
|
|
47
|
+
wallet/top-up and updater behavior. Then test the packed installation with actual
|
|
48
|
+
0.154.0 exec JSON, native model picker and bounded live test-account calls.
|
|
49
|
+
All four websites, VIP setup and generated wizard checksums must match the final
|
|
50
|
+
archive; do not repack changed files after publishing its hash.
|
|
51
|
+
|
|
52
|
+
### 2026-09-09 Configuration Safety Build
|
|
53
|
+
|
|
54
|
+
`2.0.38` is a hosted safety build for the MagnetAPI v2 Setup Wizard. npm `latest`
|
|
55
|
+
and the global mandatory minimum remain `2.0.37`; npm authentication must be
|
|
56
|
+
renewed before publishing `2.0.38` to the registry. Do not force a registry update
|
|
57
|
+
until that publication is verified. The wizard downloads the exact hosted archive,
|
|
58
|
+
verifies SHA-256, and installs the local file, avoiding npm remote-fetch restrictions.
|
|
59
|
+
The runtime remains Codex `0.153.4`; model, routing, authentication and billing
|
|
60
|
+
behavior are unchanged. `writeCodexConfig` now parses TOML with pinned
|
|
61
|
+
`@iarna/toml@2.2.5`, merges only managed root fields, the owned provider and owned
|
|
62
|
+
TUI fields, preserves other providers/MCP/projects, backs up the original, and
|
|
63
|
+
replaces the file atomically. Invalid existing TOML stops setup without changing it.
|
|
64
|
+
Run `npm test`, including the real-launcher configuration-preservation tests.
|
|
65
|
+
|
|
7
66
|
- Package name: `@codexapi/codexclaude`
|
|
8
67
|
- Launcher version: `2.0.37`
|
|
9
68
|
- Customer-facing app name: `MagnetAPI.org Codex CLI`
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codexapi/codexclaude",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "MagnetAPI.org Codex CLI for ChatGPT-6
|
|
3
|
+
"version": "2.0.39",
|
|
4
|
+
"description": "MagnetAPI.org Codex CLI for ChatGPT-6-Astra, Fable 5.1, Opus 5, Sonnet 5, Daybreak Blue, and GPT-5.6.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"node": ">=20"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@
|
|
25
|
+
"@iarna/toml": "2.2.5",
|
|
26
|
+
"@openai/codex": "0.154.0"
|
|
26
27
|
},
|
|
27
28
|
"publishConfig": {
|
|
28
29
|
"access": "public"
|