@christiandoxa/prodex 0.213.0 → 0.214.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/lib/codex-shim.cjs +316 -93
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -127,7 +127,7 @@ Runtime proxy design contract:
|
|
|
127
127
|
npm install -g @christiandoxa/prodex
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
The npm package uses its bundled `@openai/codex@latest` dependency by default. To deliberately
|
|
130
|
+
The npm package uses its bundled `@openai/codex@latest` dependency by default. If the bundled native Codex optional package is missing or not executable, Prodex falls back to an executable external `codex` on `PATH` and prints a notice before launch. This includes nvm-managed global Codex installs when the active nvm version's `bin` directory is on `PATH`. If neither bundled nor external Codex is usable, set `PRODEX_CODEX_AUTO_INSTALL=1` to let Prodex run `npm install -g @openai/codex@latest` once before retrying PATH resolution. To deliberately pin a separate Codex CLI from your machine, set `PRODEX_CODEX_BIN=/path/to/codex` or `PRODEX_CODEX_RESOLUTION=external`.
|
|
131
131
|
|
|
132
132
|
</details>
|
|
133
133
|
|
|
@@ -898,6 +898,7 @@ prodex run --rollout-budget-tokens 100000 --rollout-budget-reminders 75000,50000
|
|
|
898
898
|
|
|
899
899
|
prodex run --current-time-reminder
|
|
900
900
|
prodex run --current-time-reminder --current-time-reminder-interval 2
|
|
901
|
+
prodex run --respect-system-proxy
|
|
901
902
|
```
|
|
902
903
|
|
|
903
904
|
`--web-search` maps to Codex's top-level `web_search = "disabled" | "cached" | "indexed" | "live"` setting. In Super provider mode, an explicit `--web-search` is appended after the provider default, so it overrides the default bridge choice.
|
|
@@ -906,6 +907,8 @@ prodex run --current-time-reminder --current-time-reminder-interval 2
|
|
|
906
907
|
|
|
907
908
|
`--current-time-reminder` enables Codex's `[features.current_time_reminder]` config. The default system clock source is owned by Codex. `--current-time-clock-source external` is intended for Codex app-server clients that implement the upstream `currentTime/read` request.
|
|
908
909
|
|
|
910
|
+
`--respect-system-proxy` enables Codex's `[features.respect_system_proxy]` config when the bundled/upstream Codex supports it. Codex 0.142.1 uses this opt-in feature for Windows auth clients so PAC, WPAD, static system proxy, and bypass decisions can be honored. `--no-respect-system-proxy` renders an explicit false override for sessions that need the upstream default direct/env-proxy behavior.
|
|
911
|
+
|
|
909
912
|
Codex `multiAgentMode` is an app-server/thread setting, not a normal TUI `config.toml` launch override. Prodex therefore does not invent a competing CLI config flag. Launch `prodex app-server` or `prodex run app-server` and pass upstream `multiAgentMode` values (`none`, `explicitRequestOnly`, or `proactive`) through the Codex app-server API.
|
|
910
913
|
|
|
911
914
|
Codex plugin catalog commands are managed passthrough by default:
|
package/lib/codex-shim.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
const fs = require("node:fs");
|
|
5
5
|
const path = require("node:path");
|
|
6
|
-
const { spawn } = require("node:child_process");
|
|
6
|
+
const { spawn, spawnSync } = require("node:child_process");
|
|
7
7
|
const { createRequire } = require("node:module");
|
|
8
8
|
|
|
9
9
|
const requireFromHere = createRequire(__filename);
|
|
@@ -47,147 +47,370 @@ const PLATFORM_TARGETS = {
|
|
|
47
47
|
},
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
function
|
|
51
|
-
return PLATFORM_TARGETS[process.platform]?.[process.arch]
|
|
50
|
+
function platformSpec() {
|
|
51
|
+
return PLATFORM_TARGETS[process.platform]?.[process.arch] || null;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
function
|
|
55
|
-
let packageJsonPath;
|
|
54
|
+
function isExecutableFile(filePath) {
|
|
56
55
|
try {
|
|
57
|
-
|
|
56
|
+
const stats = fs.statSync(filePath);
|
|
57
|
+
if (!stats.isFile()) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
fs.accessSync(filePath, fs.constants.X_OK);
|
|
61
|
+
return true;
|
|
58
62
|
} catch {
|
|
59
|
-
return
|
|
63
|
+
return false;
|
|
60
64
|
}
|
|
61
|
-
return path.dirname(packageJsonPath);
|
|
62
65
|
}
|
|
63
66
|
|
|
64
|
-
function
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
function tryMakeExecutable(filePath) {
|
|
68
|
+
if (process.platform === "win32") {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const stats = fs.statSync(filePath);
|
|
73
|
+
if (stats.isFile()) {
|
|
74
|
+
fs.chmodSync(filePath, (stats.mode & 0o777) | 0o755);
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
// The explicit executable check below reports the actionable failure.
|
|
68
78
|
}
|
|
69
|
-
return {
|
|
70
|
-
...process.env,
|
|
71
|
-
CODEX_MANAGED_BY_NPM: "1",
|
|
72
|
-
CODEX_MANAGED_PACKAGE_ROOT: fs.realpathSync(packageRoot),
|
|
73
|
-
};
|
|
74
79
|
}
|
|
75
80
|
|
|
76
|
-
function
|
|
81
|
+
function managedCodexPackageRoot(fallbackRoot) {
|
|
77
82
|
try {
|
|
78
|
-
fs.
|
|
79
|
-
return;
|
|
83
|
+
return fs.realpathSync(path.dirname(requireFromHere.resolve("@openai/codex/package.json")));
|
|
80
84
|
} catch {
|
|
81
|
-
|
|
85
|
+
return fs.realpathSync(fallbackRoot);
|
|
82
86
|
}
|
|
87
|
+
}
|
|
83
88
|
|
|
89
|
+
function nativePackagePaths(spec) {
|
|
90
|
+
const packageJsonPath = requireFromHere.resolve(`${spec.packageName}/package.json`);
|
|
91
|
+
const packageRoot = path.dirname(packageJsonPath);
|
|
92
|
+
return {
|
|
93
|
+
packageRoot,
|
|
94
|
+
managedPackageRoot: managedCodexPackageRoot(packageRoot),
|
|
95
|
+
binaryPath: path.join(
|
|
96
|
+
packageRoot,
|
|
97
|
+
"vendor",
|
|
98
|
+
spec.targetTriple,
|
|
99
|
+
"bin",
|
|
100
|
+
spec.binaryFileName,
|
|
101
|
+
),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function resolveNativeCodexCommand() {
|
|
106
|
+
const spec = platformSpec();
|
|
107
|
+
if (!spec) {
|
|
108
|
+
return {
|
|
109
|
+
ok: false,
|
|
110
|
+
reason: `Unsupported Codex platform ${process.platform}/${process.arch}.`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let binaryPath;
|
|
115
|
+
let packageRoot;
|
|
116
|
+
let managedPackageRoot;
|
|
84
117
|
try {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
[
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
118
|
+
({ binaryPath, packageRoot, managedPackageRoot } = nativePackagePaths(spec));
|
|
119
|
+
} catch (error) {
|
|
120
|
+
return {
|
|
121
|
+
ok: false,
|
|
122
|
+
reason: [
|
|
123
|
+
"Unable to locate bundled Codex native package for this platform.",
|
|
124
|
+
`Missing bundled Codex native package ${spec.packageName}.`,
|
|
125
|
+
`Original error: ${error && error.message ? error.message : String(error)}`,
|
|
93
126
|
].join("\n"),
|
|
94
|
-
|
|
95
|
-
process.exit(126);
|
|
127
|
+
};
|
|
96
128
|
}
|
|
129
|
+
|
|
130
|
+
tryMakeExecutable(binaryPath);
|
|
131
|
+
|
|
132
|
+
if (!isExecutableFile(binaryPath)) {
|
|
133
|
+
return {
|
|
134
|
+
ok: false,
|
|
135
|
+
reason: `Bundled Codex native binary is not executable: ${binaryPath}`,
|
|
136
|
+
binaryPath,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
ok: true,
|
|
142
|
+
command: binaryPath,
|
|
143
|
+
args: process.argv.slice(2),
|
|
144
|
+
env: {
|
|
145
|
+
CODEX_MANAGED_BY_NPM: "1",
|
|
146
|
+
CODEX_MANAGED_PACKAGE_ROOT: managedPackageRoot,
|
|
147
|
+
},
|
|
148
|
+
};
|
|
97
149
|
}
|
|
98
150
|
|
|
99
|
-
function
|
|
100
|
-
|
|
101
|
-
|
|
151
|
+
function pathEntries() {
|
|
152
|
+
return (process.env.PATH || "")
|
|
153
|
+
.split(path.delimiter)
|
|
154
|
+
.filter((entry) => entry.length > 0);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function commandNames(command) {
|
|
158
|
+
if (process.platform !== "win32") {
|
|
159
|
+
return [command];
|
|
160
|
+
}
|
|
161
|
+
const pathext = (process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM")
|
|
162
|
+
.split(";")
|
|
163
|
+
.filter(Boolean);
|
|
164
|
+
const lower = command.toLowerCase();
|
|
165
|
+
if (pathext.some((ext) => lower.endsWith(ext.toLowerCase()))) {
|
|
166
|
+
return [command];
|
|
102
167
|
}
|
|
168
|
+
return [command, ...pathext.map((ext) => `${command}${ext}`)];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function isSelfShim(candidate) {
|
|
103
172
|
try {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return;
|
|
173
|
+
if (fs.realpathSync(candidate) === fs.realpathSync(__filename)) {
|
|
174
|
+
return true;
|
|
107
175
|
}
|
|
108
|
-
fs.chmodSync(nativeBinaryPath, (stats.mode & 0o777) | 0o755);
|
|
109
176
|
} catch {
|
|
110
|
-
//
|
|
177
|
+
// Continue with the lightweight content check.
|
|
111
178
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return null;
|
|
179
|
+
try {
|
|
180
|
+
const prefix = fs.readFileSync(candidate, "utf8").slice(0, 4096);
|
|
181
|
+
return prefix.includes(__filename);
|
|
182
|
+
} catch {
|
|
183
|
+
return false;
|
|
118
184
|
}
|
|
185
|
+
}
|
|
119
186
|
|
|
120
|
-
|
|
187
|
+
function candidateKey(candidate) {
|
|
121
188
|
try {
|
|
122
|
-
|
|
189
|
+
return fs.realpathSync(candidate).toLowerCase();
|
|
123
190
|
} catch {
|
|
124
|
-
return
|
|
191
|
+
return path.resolve(candidate).toLowerCase();
|
|
125
192
|
}
|
|
193
|
+
}
|
|
126
194
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
"
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
195
|
+
function externalCodexCandidates() {
|
|
196
|
+
const seen = new Set();
|
|
197
|
+
const candidates = [];
|
|
198
|
+
for (const dir of pathEntries()) {
|
|
199
|
+
for (const name of commandNames("codex")) {
|
|
200
|
+
const candidate = path.join(dir, name);
|
|
201
|
+
const key = candidateKey(candidate);
|
|
202
|
+
if (seen.has(key)) {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
seen.add(key);
|
|
206
|
+
candidates.push(candidate);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return candidates;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function summarizeSkippedExternalCandidates(skipped) {
|
|
213
|
+
if (skipped.length === 0) {
|
|
214
|
+
return "No codex candidates were found on PATH.";
|
|
215
|
+
}
|
|
216
|
+
const shown = skipped.slice(0, 8).map(({ candidate, reason }) => `- ${candidate} (${reason})`);
|
|
217
|
+
if (skipped.length > shown.length) {
|
|
218
|
+
shown.push(`- ... ${skipped.length - shown.length} more skipped candidates`);
|
|
143
219
|
}
|
|
144
|
-
|
|
220
|
+
return ["Searched PATH for external codex candidates:", ...shown].join("\n");
|
|
221
|
+
}
|
|
145
222
|
|
|
223
|
+
function resolveExternalCodexCommand() {
|
|
224
|
+
const skipped = [];
|
|
225
|
+
for (const candidate of externalCodexCandidates()) {
|
|
226
|
+
if (isSelfShim(candidate)) {
|
|
227
|
+
skipped.push({ candidate, reason: "Prodex Codex shim" });
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
if (!isExecutableFile(candidate)) {
|
|
231
|
+
skipped.push({ candidate, reason: "not executable" });
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
ok: true,
|
|
236
|
+
command: candidate,
|
|
237
|
+
args: process.argv.slice(2),
|
|
238
|
+
searched: skipped,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
146
241
|
return {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
242
|
+
ok: false,
|
|
243
|
+
reason: [
|
|
244
|
+
"No executable external codex was found on PATH.",
|
|
245
|
+
summarizeSkippedExternalCandidates(skipped),
|
|
246
|
+
].join("\n"),
|
|
247
|
+
searched: skipped,
|
|
150
248
|
};
|
|
151
249
|
}
|
|
152
250
|
|
|
251
|
+
|
|
252
|
+
function autoInstallCodexEnabled() {
|
|
253
|
+
return ["1", "true", "yes"].includes(
|
|
254
|
+
(process.env.PRODEX_CODEX_AUTO_INSTALL || "").toLowerCase(),
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function npmCommandNames() {
|
|
259
|
+
return commandNames("npm");
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function resolveNpmCommand() {
|
|
263
|
+
const skipped = [];
|
|
264
|
+
for (const dir of pathEntries()) {
|
|
265
|
+
for (const name of npmCommandNames()) {
|
|
266
|
+
const candidate = path.join(dir, name);
|
|
267
|
+
if (!isExecutableFile(candidate)) {
|
|
268
|
+
skipped.push({ candidate, reason: "not executable" });
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
return { ok: true, command: candidate, searched: skipped };
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return { ok: false, reason: "No executable npm was found on PATH.", searched: skipped };
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function installExternalCodexWithNpm() {
|
|
278
|
+
if (!autoInstallCodexEnabled()) {
|
|
279
|
+
return { ok: false, reason: "PRODEX_CODEX_AUTO_INSTALL is not enabled." };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const npmCommand = resolveNpmCommand();
|
|
283
|
+
if (!npmCommand.ok) {
|
|
284
|
+
return npmCommand;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
process.stderr.write(
|
|
288
|
+
[
|
|
289
|
+
"No executable external codex was found; attempting npm install because PRODEX_CODEX_AUTO_INSTALL=1.",
|
|
290
|
+
"Running: npm install -g @openai/codex@latest",
|
|
291
|
+
"",
|
|
292
|
+
].join("\n"),
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
const result = spawnSync(npmCommand.command, ["install", "-g", "@openai/codex@latest"], {
|
|
296
|
+
stdio: "inherit",
|
|
297
|
+
env: process.env,
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
if (result.error) {
|
|
301
|
+
return {
|
|
302
|
+
ok: false,
|
|
303
|
+
reason: `npm install failed to start: ${result.error.message}`,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
if (result.status !== 0) {
|
|
307
|
+
return {
|
|
308
|
+
ok: false,
|
|
309
|
+
reason: `npm install exited with status ${result.status}`,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return resolveExternalCodexCommand();
|
|
314
|
+
}
|
|
315
|
+
|
|
153
316
|
function resolveCodexCommand() {
|
|
154
317
|
const nativeCommand = resolveNativeCodexCommand();
|
|
155
|
-
if (nativeCommand) {
|
|
318
|
+
if (nativeCommand.ok) {
|
|
156
319
|
return nativeCommand;
|
|
157
320
|
}
|
|
158
321
|
|
|
322
|
+
let externalCommand = resolveExternalCodexCommand();
|
|
323
|
+
if (!externalCommand.ok && autoInstallCodexEnabled()) {
|
|
324
|
+
const installCommand = installExternalCodexWithNpm();
|
|
325
|
+
if (installCommand.ok) {
|
|
326
|
+
externalCommand = installCommand;
|
|
327
|
+
} else {
|
|
328
|
+
externalCommand = {
|
|
329
|
+
...externalCommand,
|
|
330
|
+
reason: [externalCommand.reason, installCommand.reason].filter(Boolean).join("\n"),
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (externalCommand.ok) {
|
|
336
|
+
process.stderr.write(
|
|
337
|
+
[
|
|
338
|
+
"Bundled Codex is unavailable; falling back to external codex from PATH.",
|
|
339
|
+
nativeCommand.reason,
|
|
340
|
+
summarizeSkippedExternalCandidates(externalCommand.searched || []),
|
|
341
|
+
`External codex: ${externalCommand.command}`,
|
|
342
|
+
"Set PRODEX_CODEX_BIN to pin a specific Codex executable.",
|
|
343
|
+
"",
|
|
344
|
+
].join("\n"),
|
|
345
|
+
);
|
|
346
|
+
return externalCommand;
|
|
347
|
+
}
|
|
348
|
+
|
|
159
349
|
process.stderr.write(
|
|
160
350
|
[
|
|
161
|
-
"Unable to locate bundled Codex native package for this platform.",
|
|
162
|
-
"Reinstall @christiandoxa/prodex with optional dependencies enabled,
|
|
351
|
+
nativeCommand.reason || "Unable to locate bundled Codex native package for this platform.",
|
|
352
|
+
"Reinstall @christiandoxa/prodex with optional dependencies enabled, set PRODEX_CODEX_BIN to an existing Codex CLI, or set PRODEX_CODEX_AUTO_INSTALL=1 to let Prodex run npm install -g @openai/codex@latest.",
|
|
163
353
|
"Prodex does not fall back to @openai/codex/bin/codex.js because npm/Node version skew can make Codex load the wrong optional native package.",
|
|
354
|
+
externalCommand.reason,
|
|
164
355
|
"",
|
|
165
356
|
].join("\n"),
|
|
166
357
|
);
|
|
167
358
|
process.exit(1);
|
|
168
359
|
}
|
|
169
360
|
|
|
170
|
-
|
|
171
|
-
const child = spawn(codexCommand.command, codexCommand.args, {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
361
|
+
function spawnCodex(codexCommand, retriedExternalFallback = false) {
|
|
362
|
+
const child = spawn(codexCommand.command, codexCommand.args, {
|
|
363
|
+
stdio: "inherit",
|
|
364
|
+
env: {
|
|
365
|
+
...process.env,
|
|
366
|
+
...(codexCommand.env || {}),
|
|
367
|
+
},
|
|
368
|
+
});
|
|
175
369
|
|
|
176
|
-
child.on("error", (error) => {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
370
|
+
child.on("error", (error) => {
|
|
371
|
+
if (error && error.code === "EACCES" && !retriedExternalFallback) {
|
|
372
|
+
let externalCommand = resolveExternalCodexCommand();
|
|
373
|
+
if (!externalCommand.ok && autoInstallCodexEnabled()) {
|
|
374
|
+
const installCommand = installExternalCodexWithNpm();
|
|
375
|
+
if (installCommand.ok) {
|
|
376
|
+
externalCommand = installCommand;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (externalCommand.ok && externalCommand.command !== codexCommand.command) {
|
|
380
|
+
process.stderr.write(
|
|
381
|
+
[
|
|
382
|
+
`${error.message}`,
|
|
383
|
+
"Bundled Codex could not be executed; falling back to external codex from PATH.",
|
|
384
|
+
summarizeSkippedExternalCandidates(externalCommand.searched || []),
|
|
385
|
+
`External codex: ${externalCommand.command}`,
|
|
386
|
+
"Set PRODEX_CODEX_BIN to pin a specific Codex executable.",
|
|
387
|
+
"",
|
|
388
|
+
].join("\n"),
|
|
389
|
+
);
|
|
390
|
+
spawnCodex(externalCommand, true);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
186
394
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
395
|
+
if (error && error.code === "EACCES") {
|
|
396
|
+
process.stderr.write(
|
|
397
|
+
`${error.message}\nSet PRODEX_CODEX_BIN to an existing Codex CLI, set PRODEX_CODEX_AUTO_INSTALL=1 to let Prodex run npm install -g @openai/codex@latest, or reinstall @christiandoxa/prodex.\n`,
|
|
398
|
+
);
|
|
399
|
+
process.exit(126);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
process.stderr.write(`${error && error.message ? error.message : String(error)}\n`);
|
|
404
|
+
process.exit(1);
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
child.on("exit", (code, signal) => {
|
|
408
|
+
if (signal) {
|
|
409
|
+
process.kill(process.pid, signal);
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
process.exit(code ?? 1);
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
spawnCodex(resolveCodexCommand());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@christiandoxa/prodex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.214.0",
|
|
4
4
|
"description": "Multi-provider Codex wrapper with OpenAI quota-aware routing and Claude Code support",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"bin": {
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
"@openai/codex": "latest"
|
|
17
17
|
},
|
|
18
18
|
"optionalDependencies": {
|
|
19
|
-
"@christiandoxa/prodex-linux-x64": "0.
|
|
20
|
-
"@christiandoxa/prodex-linux-arm64": "0.
|
|
21
|
-
"@christiandoxa/prodex-darwin-x64": "0.
|
|
22
|
-
"@christiandoxa/prodex-darwin-arm64": "0.
|
|
23
|
-
"@christiandoxa/prodex-win32-x64": "0.
|
|
24
|
-
"@christiandoxa/prodex-win32-arm64": "0.
|
|
19
|
+
"@christiandoxa/prodex-linux-x64": "0.214.0",
|
|
20
|
+
"@christiandoxa/prodex-linux-arm64": "0.214.0",
|
|
21
|
+
"@christiandoxa/prodex-darwin-x64": "0.214.0",
|
|
22
|
+
"@christiandoxa/prodex-darwin-arm64": "0.214.0",
|
|
23
|
+
"@christiandoxa/prodex-win32-x64": "0.214.0",
|
|
24
|
+
"@christiandoxa/prodex-win32-arm64": "0.214.0",
|
|
25
25
|
"@openai/codex-linux-x64": "npm:@openai/codex@linux-x64",
|
|
26
26
|
"@openai/codex-linux-arm64": "npm:@openai/codex@linux-arm64",
|
|
27
27
|
"@openai/codex-darwin-x64": "npm:@openai/codex@darwin-x64",
|