codexuse-cli 3.8.1 → 3.9.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/dist/index.js +496 -141
- package/dist/index.js.map +1 -1
- package/dist/server/{NodeSqliteClient-8mlwim6r.mjs → NodeSqliteClient-Cx2_VxdP.mjs} +9 -10
- package/dist/server/{SqlError-4YSIrGT4.mjs → SqlError-CoqftVSq.mjs} +2 -2
- package/dist/server/{SqliteClient-DkbUL5wr.mjs → SqliteClient-CXjquy8x.mjs} +3 -3
- package/dist/server/index.mjs +32075 -1844
- package/dist/server/{open-BM96ykXl.mjs → open-DX6_a9Ta.mjs} +1 -1
- package/package.json +2 -2
- package/dist/server/SqlClient-8hJa5MAm.mjs +0 -27647
package/dist/index.js
CHANGED
|
@@ -2352,7 +2352,8 @@ function createDefaultAppState() {
|
|
|
2352
2352
|
autoRoll: {
|
|
2353
2353
|
enabled: false,
|
|
2354
2354
|
warningThreshold: 85,
|
|
2355
|
-
switchThreshold: 95
|
|
2355
|
+
switchThreshold: 95,
|
|
2356
|
+
restartOfficialCodexOnAutoRoll: false
|
|
2356
2357
|
},
|
|
2357
2358
|
app: {
|
|
2358
2359
|
lastAppVersion: null,
|
|
@@ -2479,6 +2480,9 @@ function normalizeAppState(raw) {
|
|
|
2479
2480
|
Math.max(merged.autoRoll.warningThreshold + 1, 95)
|
|
2480
2481
|
);
|
|
2481
2482
|
}
|
|
2483
|
+
if (typeof merged.autoRoll.restartOfficialCodexOnAutoRoll !== "boolean") {
|
|
2484
|
+
merged.autoRoll.restartOfficialCodexOnAutoRoll = false;
|
|
2485
|
+
}
|
|
2482
2486
|
merged.app.lastAppVersion = asString(merged.app.lastAppVersion);
|
|
2483
2487
|
merged.app.pendingUpdateVersion = asString(merged.app.pendingUpdateVersion);
|
|
2484
2488
|
merged.app.lastProfileName = asString(merged.app.lastProfileName);
|
|
@@ -2872,6 +2876,7 @@ async function patchAppState(patch) {
|
|
|
2872
2876
|
}
|
|
2873
2877
|
|
|
2874
2878
|
// ../../packages/runtime-app-state/src/app/runtimeSettings.ts
|
|
2879
|
+
var CUSTOMER_DEFAULTS_MIGRATION_KEY = "customerRateLimitBackgroundDefaultsApplied";
|
|
2875
2880
|
var LEGACY_APP_SETTINGS_KEYS = /* @__PURE__ */ new Set([
|
|
2876
2881
|
"backendMode",
|
|
2877
2882
|
"theme",
|
|
@@ -2899,12 +2904,56 @@ function stripLegacyAppSettingsKeys(settings) {
|
|
|
2899
2904
|
}
|
|
2900
2905
|
return changed ? next : settings;
|
|
2901
2906
|
}
|
|
2907
|
+
function withCurrentRuntimeDefaults(settings, options) {
|
|
2908
|
+
let changed = false;
|
|
2909
|
+
const next = { ...settings };
|
|
2910
|
+
const migrationApplied = next[CUSTOMER_DEFAULTS_MIGRATION_KEY] === true;
|
|
2911
|
+
if (options.migrateLegacyDefaults && !migrationApplied) {
|
|
2912
|
+
if (!("keepAppRunningAfterWindowClose" in next)) {
|
|
2913
|
+
next.keepAppRunningAfterWindowClose = true;
|
|
2914
|
+
changed = true;
|
|
2915
|
+
}
|
|
2916
|
+
} else if (!("keepAppRunningAfterWindowClose" in next)) {
|
|
2917
|
+
next.keepAppRunningAfterWindowClose = true;
|
|
2918
|
+
changed = true;
|
|
2919
|
+
}
|
|
2920
|
+
if (next.rateLimitPercentMode !== "remaining" && next.rateLimitPercentMode !== "used") {
|
|
2921
|
+
next.rateLimitPercentMode = "remaining";
|
|
2922
|
+
changed = true;
|
|
2923
|
+
}
|
|
2924
|
+
if (!migrationApplied) {
|
|
2925
|
+
next[CUSTOMER_DEFAULTS_MIGRATION_KEY] = true;
|
|
2926
|
+
changed = true;
|
|
2927
|
+
}
|
|
2928
|
+
return { settings: changed ? next : settings, changed };
|
|
2929
|
+
}
|
|
2902
2930
|
async function readAppSettings() {
|
|
2903
2931
|
const appState = await getAppState();
|
|
2904
|
-
|
|
2932
|
+
const stripped = stripLegacyAppSettingsKeys(asRecord(appState.runtimeSettings));
|
|
2933
|
+
const next = withCurrentRuntimeDefaults(stripped, {
|
|
2934
|
+
migrateLegacyDefaults: true
|
|
2935
|
+
});
|
|
2936
|
+
if (next.changed) {
|
|
2937
|
+
await updateAppState(
|
|
2938
|
+
(current) => ({
|
|
2939
|
+
...current,
|
|
2940
|
+
runtimeSettings: next.settings
|
|
2941
|
+
}),
|
|
2942
|
+
{
|
|
2943
|
+
mode: "replace",
|
|
2944
|
+
allowBeforeMigrationComplete: false
|
|
2945
|
+
}
|
|
2946
|
+
);
|
|
2947
|
+
}
|
|
2948
|
+
return next.settings;
|
|
2905
2949
|
}
|
|
2906
2950
|
async function writeAppSettings(settings, onUpdated) {
|
|
2907
|
-
const nextSettings =
|
|
2951
|
+
const nextSettings = withCurrentRuntimeDefaults(
|
|
2952
|
+
stripLegacyAppSettingsKeys(asRecord(settings)),
|
|
2953
|
+
{
|
|
2954
|
+
migrateLegacyDefaults: false
|
|
2955
|
+
}
|
|
2956
|
+
).settings;
|
|
2908
2957
|
await updateAppState(
|
|
2909
2958
|
(current) => ({
|
|
2910
2959
|
...current,
|
|
@@ -2932,6 +2981,7 @@ var import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
|
2932
2981
|
var DEFAULT_AUTO_ROLL_ENABLED = false;
|
|
2933
2982
|
var DEFAULT_AUTO_ROLL_WARNING_THRESHOLD = 85;
|
|
2934
2983
|
var DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD = 95;
|
|
2984
|
+
var DEFAULT_RESTART_OFFICIAL_CODEX_ON_AUTO_ROLL = false;
|
|
2935
2985
|
var AUTO_ROLL_WARNING_MIN = 50;
|
|
2936
2986
|
var AUTO_ROLL_WARNING_MAX = 99;
|
|
2937
2987
|
var AUTO_ROLL_SWITCH_MAX = 100;
|
|
@@ -2975,7 +3025,8 @@ function normalizeAutoRollSettings(raw) {
|
|
|
2975
3025
|
return {
|
|
2976
3026
|
enabled,
|
|
2977
3027
|
warningThreshold: normalizedWarning,
|
|
2978
|
-
switchThreshold: normalizedSwitch
|
|
3028
|
+
switchThreshold: normalizedSwitch,
|
|
3029
|
+
restartOfficialCodexOnAutoRoll: raw?.restartOfficialCodexOnAutoRoll === true ? true : DEFAULT_RESTART_OFFICIAL_CODEX_ON_AUTO_ROLL
|
|
2979
3030
|
};
|
|
2980
3031
|
}
|
|
2981
3032
|
|
|
@@ -3100,7 +3151,8 @@ async function writeCodexSettingsJsonRaw(payload) {
|
|
|
3100
3151
|
autoRoll: autoRoll ? {
|
|
3101
3152
|
enabled: autoRoll.enabled,
|
|
3102
3153
|
warningThreshold: autoRoll.warningThreshold,
|
|
3103
|
-
switchThreshold: autoRoll.switchThreshold
|
|
3154
|
+
switchThreshold: autoRoll.switchThreshold,
|
|
3155
|
+
restartOfficialCodexOnAutoRoll: autoRoll.restartOfficialCodexOnAutoRoll
|
|
3104
3156
|
} : void 0,
|
|
3105
3157
|
license: license ? {
|
|
3106
3158
|
licenseKey: license.licenseKey ?? null,
|
|
@@ -5802,7 +5854,12 @@ function printHelp(version) {
|
|
|
5802
5854
|
console.log(`CodexUse CLI v${version}
|
|
5803
5855
|
|
|
5804
5856
|
Usage:
|
|
5857
|
+
codexuse doctor
|
|
5858
|
+
codexuse run --profile <name> -- <codex args>
|
|
5859
|
+
codexuse best [--dry-run] -- <codex args>
|
|
5860
|
+
|
|
5805
5861
|
codexuse account-pool status [--runtime=desktop|daemon] [--state-dir=/abs/path] [--port=NNNN]
|
|
5862
|
+
codexuse account-pool quickstart
|
|
5806
5863
|
codexuse account-pool enable
|
|
5807
5864
|
codexuse account-pool disable
|
|
5808
5865
|
codexuse account-pool routing <least-used|round-robin>
|
|
@@ -5842,6 +5899,7 @@ Flags:
|
|
|
5842
5899
|
--watch Keep checking and auto-switch when threshold is reached
|
|
5843
5900
|
--interval=SEC Watch interval in seconds (default: 30)
|
|
5844
5901
|
--dry-run Print planned switch without changing active profile
|
|
5902
|
+
--profile=NAME Run Codex with one saved profile
|
|
5845
5903
|
--runtime=NAME Accounts Pool runtime store: desktop | daemon
|
|
5846
5904
|
--state-dir=PATH Override the runtime state dir for Accounts Pool inspection
|
|
5847
5905
|
--port=NNNN Stable daemon/API port (or use with account-pool status for daemon base URL)
|
|
@@ -6053,6 +6111,7 @@ function printAccountPoolHelp(version) {
|
|
|
6053
6111
|
|
|
6054
6112
|
Usage:
|
|
6055
6113
|
codexuse account-pool status [--runtime=desktop|daemon] [--state-dir=/abs/path] [--port=NNNN]
|
|
6114
|
+
codexuse account-pool quickstart [--runtime=desktop|daemon] [--state-dir=/abs/path] [--port=NNNN]
|
|
6056
6115
|
codexuse account-pool enable
|
|
6057
6116
|
codexuse account-pool disable
|
|
6058
6117
|
codexuse account-pool routing <least-used|round-robin>
|
|
@@ -6833,6 +6892,28 @@ async function handleSessions(params, flags) {
|
|
|
6833
6892
|
}
|
|
6834
6893
|
console.log("Session mutation is intentionally not exposed here; pooled sessions belong to the live runtime owner.");
|
|
6835
6894
|
}
|
|
6895
|
+
async function handleQuickstart(flags) {
|
|
6896
|
+
const { runtime, stateDir } = resolveStateDir(flags);
|
|
6897
|
+
const port = parseIntegerFlag(flags, "--port");
|
|
6898
|
+
const summary = await readAccountPoolRuntimeSummary({ runtime, stateDir, port });
|
|
6899
|
+
const baseUrl = summary.baseUrl ?? "http://127.0.0.1:<port>";
|
|
6900
|
+
console.log("Accounts Pool quickstart");
|
|
6901
|
+
console.log(`Runtime: ${summary.runtime}`);
|
|
6902
|
+
console.log(`Enabled: ${summary.enabled ? "yes" : "no"}`);
|
|
6903
|
+
console.log(`Pro: ${summary.hasProLicense ? "yes" : "no"}`);
|
|
6904
|
+
console.log(`API keys: ${summary.activeApiKeyCount}`);
|
|
6905
|
+
console.log(`Base URL: ${baseUrl}`);
|
|
6906
|
+
console.log("");
|
|
6907
|
+
console.log("1. Enable pool:");
|
|
6908
|
+
console.log(" codexuse account-pool enable");
|
|
6909
|
+
console.log("2. Create key:");
|
|
6910
|
+
console.log(` codexuse account-pool keys create --runtime=${summary.runtime}`);
|
|
6911
|
+
console.log("3. Use OpenAI-compatible settings:");
|
|
6912
|
+
console.log(` Base URL: ${baseUrl}/v1`);
|
|
6913
|
+
console.log(" API key: cux_pool_...");
|
|
6914
|
+
console.log("4. Smoke:");
|
|
6915
|
+
console.log(` curl ${baseUrl}/v1/models -H 'Authorization: Bearer cux_pool_...'`);
|
|
6916
|
+
}
|
|
6836
6917
|
async function handleAccountPoolCommand(args, version) {
|
|
6837
6918
|
const flags = args.filter((arg) => arg.startsWith("-"));
|
|
6838
6919
|
const params = stripFlags(args);
|
|
@@ -6845,6 +6926,9 @@ async function handleAccountPoolCommand(args, version) {
|
|
|
6845
6926
|
case "status":
|
|
6846
6927
|
await handleStatus(flags);
|
|
6847
6928
|
return;
|
|
6929
|
+
case "quickstart":
|
|
6930
|
+
await handleQuickstart(flags);
|
|
6931
|
+
return;
|
|
6848
6932
|
case "enable":
|
|
6849
6933
|
await handleEnable();
|
|
6850
6934
|
return;
|
|
@@ -6899,39 +6983,404 @@ async function handleAccountPoolCommand(args, version) {
|
|
|
6899
6983
|
}
|
|
6900
6984
|
}
|
|
6901
6985
|
|
|
6902
|
-
// src/commands/
|
|
6986
|
+
// src/commands/codex.ts
|
|
6903
6987
|
var import_node_child_process4 = require("child_process");
|
|
6988
|
+
|
|
6989
|
+
// ../../packages/runtime-profiles/src/profiles/rate-limit-notifier.ts
|
|
6990
|
+
function maxUsedPercent(snapshot) {
|
|
6991
|
+
if (!snapshot) {
|
|
6992
|
+
return null;
|
|
6993
|
+
}
|
|
6994
|
+
const candidates = [
|
|
6995
|
+
snapshot.primary?.usedPercent,
|
|
6996
|
+
snapshot.secondary?.usedPercent
|
|
6997
|
+
].filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
6998
|
+
if (candidates.length === 0) {
|
|
6999
|
+
return null;
|
|
7000
|
+
}
|
|
7001
|
+
return Math.max(...candidates);
|
|
7002
|
+
}
|
|
7003
|
+
|
|
7004
|
+
// src/platform/codexCli.ts
|
|
7005
|
+
var import_node_child_process3 = require("child_process");
|
|
7006
|
+
var import_node_fs6 = require("fs");
|
|
7007
|
+
var import_node_path8 = __toESM(require("path"));
|
|
7008
|
+
var ENV_HINTS2 = ["CODEX_BINARY", "CODEX_CLI_PATH", "CODEX_PATH"];
|
|
7009
|
+
function fileExists2(candidate) {
|
|
7010
|
+
if (!candidate) return null;
|
|
7011
|
+
const resolved = import_node_path8.default.resolve(candidate);
|
|
7012
|
+
try {
|
|
7013
|
+
const stat2 = (0, import_node_fs6.statSync)(resolved);
|
|
7014
|
+
if (stat2.isFile()) return resolved;
|
|
7015
|
+
} catch {
|
|
7016
|
+
return null;
|
|
7017
|
+
}
|
|
7018
|
+
return null;
|
|
7019
|
+
}
|
|
7020
|
+
function resolveFromEnv() {
|
|
7021
|
+
for (const key of ENV_HINTS2) {
|
|
7022
|
+
const value = process.env[key];
|
|
7023
|
+
if (!value) continue;
|
|
7024
|
+
const resolved = fileExists2(value);
|
|
7025
|
+
if (resolved) return resolved;
|
|
7026
|
+
}
|
|
7027
|
+
return null;
|
|
7028
|
+
}
|
|
7029
|
+
function resolveFromPath() {
|
|
7030
|
+
const pathValue = process.env.PATH ?? "";
|
|
7031
|
+
const entries = pathValue.split(import_node_path8.default.delimiter).filter(Boolean);
|
|
7032
|
+
const names = process.platform === "win32" ? ["codex.exe", "codex.cmd", "codex.bat", "codex"] : ["codex"];
|
|
7033
|
+
for (const entry of entries) {
|
|
7034
|
+
for (const name of names) {
|
|
7035
|
+
const candidate = fileExists2(import_node_path8.default.join(entry, name));
|
|
7036
|
+
if (candidate) return candidate;
|
|
7037
|
+
}
|
|
7038
|
+
}
|
|
7039
|
+
return null;
|
|
7040
|
+
}
|
|
7041
|
+
function resolveCodexBinary() {
|
|
7042
|
+
return resolveFromEnv() || resolveFromPath();
|
|
7043
|
+
}
|
|
7044
|
+
function requireCodexBinary(context) {
|
|
7045
|
+
const resolved = resolveCodexBinary();
|
|
7046
|
+
if (resolved) return resolved;
|
|
7047
|
+
const hint = "Install Codex CLI (npm i -g @openai/codex) or set CODEX_BINARY.";
|
|
7048
|
+
const message = context ? `${context} ${hint}` : hint;
|
|
7049
|
+
throw new Error(message);
|
|
7050
|
+
}
|
|
7051
|
+
function buildCodexCommand2(codexPath, args) {
|
|
7052
|
+
const normalized = codexPath.toLowerCase();
|
|
7053
|
+
const isJs = normalized.endsWith(".js") || normalized.endsWith(".mjs") || normalized.endsWith(".cjs");
|
|
7054
|
+
if (isJs) {
|
|
7055
|
+
return { command: process.execPath, args: [codexPath, ...args], shell: false };
|
|
7056
|
+
}
|
|
7057
|
+
const useShell = process.platform === "win32";
|
|
7058
|
+
return { command: codexPath, args, shell: useShell };
|
|
7059
|
+
}
|
|
7060
|
+
function isHeadless() {
|
|
7061
|
+
if (process.env.CODEXUSE_HEADLESS === "1") return true;
|
|
7062
|
+
if (process.env.CI) return true;
|
|
7063
|
+
if (process.env.SSH_CONNECTION || process.env.SSH_TTY) return true;
|
|
7064
|
+
if (process.platform === "linux") {
|
|
7065
|
+
if (!process.env.DISPLAY && !process.env.WAYLAND_DISPLAY) return true;
|
|
7066
|
+
}
|
|
7067
|
+
return false;
|
|
7068
|
+
}
|
|
7069
|
+
function resolveLoginMode(preferred) {
|
|
7070
|
+
if (preferred === "browser" || preferred === "device") {
|
|
7071
|
+
return preferred;
|
|
7072
|
+
}
|
|
7073
|
+
const envMode = process.env.CODEXUSE_LOGIN_MODE;
|
|
7074
|
+
if (envMode === "browser" || envMode === "device") {
|
|
7075
|
+
return envMode;
|
|
7076
|
+
}
|
|
7077
|
+
return isHeadless() ? "device" : "browser";
|
|
7078
|
+
}
|
|
7079
|
+
async function runCodexLogin(mode) {
|
|
7080
|
+
const codexPath = requireCodexBinary("Codex CLI is required to login.");
|
|
7081
|
+
const resolvedMode = resolveLoginMode(mode ?? null);
|
|
7082
|
+
const loginArgs = resolvedMode === "device" ? ["login", "--device-auth"] : ["login"];
|
|
7083
|
+
const { command, args, shell } = buildCodexCommand2(codexPath, loginArgs);
|
|
7084
|
+
const child = (0, import_node_child_process3.spawn)(command, args, {
|
|
7085
|
+
stdio: "inherit",
|
|
7086
|
+
env: process.env,
|
|
7087
|
+
shell
|
|
7088
|
+
});
|
|
7089
|
+
const exitCode = await new Promise((resolve) => {
|
|
7090
|
+
child.on("close", (code) => resolve(code ?? 0));
|
|
7091
|
+
});
|
|
7092
|
+
if (exitCode !== 0) {
|
|
7093
|
+
throw new Error(`Codex CLI login failed (exit code ${exitCode}).`);
|
|
7094
|
+
}
|
|
7095
|
+
}
|
|
7096
|
+
|
|
7097
|
+
// src/commands/codex.ts
|
|
7098
|
+
var DOCTOR_TIMEOUT_MS = 8e3;
|
|
7099
|
+
function splitCommandArgs(args) {
|
|
7100
|
+
const delimiterIndex = args.indexOf("--");
|
|
7101
|
+
const flags = delimiterIndex >= 0 ? args.slice(0, delimiterIndex) : args.slice();
|
|
7102
|
+
const codexArgs = delimiterIndex >= 0 ? args.slice(delimiterIndex + 1) : [];
|
|
7103
|
+
return { flags, codexArgs };
|
|
7104
|
+
}
|
|
7105
|
+
function readOption(flags, longName, shortName) {
|
|
7106
|
+
for (let index = 0; index < flags.length; index += 1) {
|
|
7107
|
+
const flag = flags[index];
|
|
7108
|
+
if (flag === longName) {
|
|
7109
|
+
const next = flags[index + 1];
|
|
7110
|
+
return next && !next.startsWith("-") ? next : "";
|
|
7111
|
+
}
|
|
7112
|
+
if (flag.startsWith(`${longName}=`)) {
|
|
7113
|
+
return flag.slice(longName.length + 1).trim();
|
|
7114
|
+
}
|
|
7115
|
+
if (shortName && flag === shortName) {
|
|
7116
|
+
const next = flags[index + 1];
|
|
7117
|
+
return next && !next.startsWith("-") ? next : "";
|
|
7118
|
+
}
|
|
7119
|
+
}
|
|
7120
|
+
return null;
|
|
7121
|
+
}
|
|
7122
|
+
function firstLine(value) {
|
|
7123
|
+
const line = value.split(/\r?\n/).map((entry) => entry.trim()).find(Boolean);
|
|
7124
|
+
return line ?? null;
|
|
7125
|
+
}
|
|
7126
|
+
function formatUsagePercent(value) {
|
|
7127
|
+
return typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}%` : "unknown";
|
|
7128
|
+
}
|
|
7129
|
+
function snapshotResetSeconds(snapshot) {
|
|
7130
|
+
const values = [
|
|
7131
|
+
snapshot?.primary?.resetsInSeconds,
|
|
7132
|
+
snapshot?.secondary?.resetsInSeconds
|
|
7133
|
+
].filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
7134
|
+
return values.length > 0 ? Math.min(...values) : null;
|
|
7135
|
+
}
|
|
7136
|
+
function fallbackUsedPercent(profile) {
|
|
7137
|
+
const cached = maxUsedPercent(profile.rateLimit ?? null);
|
|
7138
|
+
return typeof cached === "number" && Number.isFinite(cached) ? cached : null;
|
|
7139
|
+
}
|
|
7140
|
+
function compareCandidates(left, right) {
|
|
7141
|
+
const leftUsage = left.usedPercent ?? Number.POSITIVE_INFINITY;
|
|
7142
|
+
const rightUsage = right.usedPercent ?? Number.POSITIVE_INFINITY;
|
|
7143
|
+
if (leftUsage !== rightUsage) {
|
|
7144
|
+
return leftUsage - rightUsage;
|
|
7145
|
+
}
|
|
7146
|
+
const leftReset = left.resetSeconds ?? Number.POSITIVE_INFINITY;
|
|
7147
|
+
const rightReset = right.resetSeconds ?? Number.POSITIVE_INFINITY;
|
|
7148
|
+
if (leftReset !== rightReset) {
|
|
7149
|
+
return leftReset - rightReset;
|
|
7150
|
+
}
|
|
7151
|
+
return left.profile.name.localeCompare(right.profile.name);
|
|
7152
|
+
}
|
|
7153
|
+
async function runCommand(codexPath, args, timeoutMs) {
|
|
7154
|
+
const command = buildCodexCommand2(codexPath, args);
|
|
7155
|
+
return new Promise((resolve) => {
|
|
7156
|
+
const child = (0, import_node_child_process4.spawn)(command.command, command.args, {
|
|
7157
|
+
env: process.env,
|
|
7158
|
+
shell: command.shell,
|
|
7159
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
7160
|
+
});
|
|
7161
|
+
let stdout = "";
|
|
7162
|
+
let stderr = "";
|
|
7163
|
+
let settled = false;
|
|
7164
|
+
let timedOut = false;
|
|
7165
|
+
let timer;
|
|
7166
|
+
const finish = (code) => {
|
|
7167
|
+
if (settled) {
|
|
7168
|
+
return;
|
|
7169
|
+
}
|
|
7170
|
+
settled = true;
|
|
7171
|
+
clearTimeout(timer);
|
|
7172
|
+
resolve({ code, stdout, stderr, timedOut });
|
|
7173
|
+
};
|
|
7174
|
+
timer = setTimeout(() => {
|
|
7175
|
+
timedOut = true;
|
|
7176
|
+
child.kill("SIGTERM");
|
|
7177
|
+
finish(null);
|
|
7178
|
+
}, timeoutMs);
|
|
7179
|
+
child.stdout?.on("data", (chunk) => {
|
|
7180
|
+
stdout += String(chunk).slice(0, 2e4);
|
|
7181
|
+
});
|
|
7182
|
+
child.stderr?.on("data", (chunk) => {
|
|
7183
|
+
stderr += String(chunk).slice(0, 2e4);
|
|
7184
|
+
});
|
|
7185
|
+
child.on("error", () => finish(null));
|
|
7186
|
+
child.on("close", (code) => finish(code));
|
|
7187
|
+
});
|
|
7188
|
+
}
|
|
7189
|
+
async function selectBestProfile(manager, profiles, codexPath) {
|
|
7190
|
+
const candidates = [];
|
|
7191
|
+
for (const profile of profiles) {
|
|
7192
|
+
if (!profile.isValid || profile.tokenStatus?.requiresUserAction) {
|
|
7193
|
+
continue;
|
|
7194
|
+
}
|
|
7195
|
+
try {
|
|
7196
|
+
const snapshot = await manager.readLiveRateLimits(profile.name, { codexPath });
|
|
7197
|
+
candidates.push({
|
|
7198
|
+
profile,
|
|
7199
|
+
usedPercent: typeof maxUsedPercent(snapshot) === "number" ? maxUsedPercent(snapshot) : fallbackUsedPercent(profile),
|
|
7200
|
+
resetSeconds: snapshotResetSeconds(snapshot)
|
|
7201
|
+
});
|
|
7202
|
+
} catch {
|
|
7203
|
+
candidates.push({
|
|
7204
|
+
profile,
|
|
7205
|
+
usedPercent: fallbackUsedPercent(profile),
|
|
7206
|
+
resetSeconds: snapshotResetSeconds(profile.rateLimit ?? null)
|
|
7207
|
+
});
|
|
7208
|
+
}
|
|
7209
|
+
}
|
|
7210
|
+
return candidates.sort(compareCandidates)[0] ?? null;
|
|
7211
|
+
}
|
|
7212
|
+
async function runCodexWithProfile(manager, profileName, codexArgs) {
|
|
7213
|
+
const codexPath = resolveCodexBinary();
|
|
7214
|
+
if (!codexPath) {
|
|
7215
|
+
throw new Error("Codex CLI not found. Install Codex CLI or set CODEX_BINARY.");
|
|
7216
|
+
}
|
|
7217
|
+
const runtime = await manager.prepareProfileRuntime(profileName);
|
|
7218
|
+
const command = buildCodexCommand2(codexPath, codexArgs);
|
|
7219
|
+
try {
|
|
7220
|
+
const child = (0, import_node_child_process4.spawn)(command.command, command.args, {
|
|
7221
|
+
env: runtime.env,
|
|
7222
|
+
shell: command.shell,
|
|
7223
|
+
stdio: "inherit"
|
|
7224
|
+
});
|
|
7225
|
+
const exitCode = await new Promise((resolve) => {
|
|
7226
|
+
child.on("close", (code) => resolve(code ?? 0));
|
|
7227
|
+
});
|
|
7228
|
+
process.exitCode = exitCode;
|
|
7229
|
+
} finally {
|
|
7230
|
+
await manager.syncProfileRuntime(profileName, runtime.profileHome).catch((error) => {
|
|
7231
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7232
|
+
console.error(`Warning: failed to sync profile runtime for '${profileName}': ${message}`);
|
|
7233
|
+
});
|
|
7234
|
+
}
|
|
7235
|
+
}
|
|
7236
|
+
async function handleDoctorCommand(args) {
|
|
7237
|
+
if (hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
7238
|
+
console.log(`Usage:
|
|
7239
|
+
codexuse doctor
|
|
7240
|
+
|
|
7241
|
+
Checks Codex CLI, auth, saved profiles, license, and Accounts Pool readiness.`);
|
|
7242
|
+
return;
|
|
7243
|
+
}
|
|
7244
|
+
const manager = new ProfileManager();
|
|
7245
|
+
const codexPath = resolveCodexBinary();
|
|
7246
|
+
const [profiles, current, license, accountPool] = await Promise.all([
|
|
7247
|
+
manager.listProfiles(),
|
|
7248
|
+
manager.getCurrentProfile(),
|
|
7249
|
+
licenseService.getStatus().catch(() => null),
|
|
7250
|
+
readAccountPoolRuntimeSummary().catch(() => null)
|
|
7251
|
+
]);
|
|
7252
|
+
console.log("CodexUse Doctor");
|
|
7253
|
+
if (!codexPath) {
|
|
7254
|
+
console.log("Codex CLI: missing");
|
|
7255
|
+
} else {
|
|
7256
|
+
const version = await runCommand(codexPath, ["--version"], DOCTOR_TIMEOUT_MS);
|
|
7257
|
+
const versionText = firstLine(version.stdout) ?? firstLine(version.stderr);
|
|
7258
|
+
console.log(`Codex CLI: ${version.code === 0 ? "ok" : "check"} (${codexPath})`);
|
|
7259
|
+
console.log(`Version: ${versionText ?? (version.timedOut ? "timed out" : "unknown")}`);
|
|
7260
|
+
const auth = await runCommand(codexPath, ["login", "status"], DOCTOR_TIMEOUT_MS);
|
|
7261
|
+
const authText = firstLine(auth.stdout) ?? firstLine(auth.stderr);
|
|
7262
|
+
console.log(`Auth: ${auth.code === 0 ? "ok" : "check"}${authText ? ` (${authText})` : ""}`);
|
|
7263
|
+
}
|
|
7264
|
+
console.log(`Profiles: ${profiles.length}`);
|
|
7265
|
+
console.log(`Active profile: ${current.name ?? "none"}${current.trusted ? "" : " (untrusted)"}`);
|
|
7266
|
+
console.log(`License: ${license ? `${license.tier} (${license.state})` : "unknown"}`);
|
|
7267
|
+
if (accountPool) {
|
|
7268
|
+
console.log(
|
|
7269
|
+
`Accounts Pool: ${accountPool.enabled ? "on" : "off"} | keys ${accountPool.activeApiKeyCount} | sessions ${accountPool.activeSessionCount}`
|
|
7270
|
+
);
|
|
7271
|
+
} else {
|
|
7272
|
+
console.log("Accounts Pool: unknown");
|
|
7273
|
+
}
|
|
7274
|
+
const fixes = [];
|
|
7275
|
+
if (!codexPath) {
|
|
7276
|
+
fixes.push("Install Codex CLI or set CODEX_BINARY.");
|
|
7277
|
+
}
|
|
7278
|
+
if (profiles.length === 0) {
|
|
7279
|
+
fixes.push("Add first profile: codexuse profile add personal");
|
|
7280
|
+
}
|
|
7281
|
+
if (profiles.length === 1) {
|
|
7282
|
+
fixes.push("Add second profile: codexuse profile add work");
|
|
7283
|
+
}
|
|
7284
|
+
if (!current.name && profiles.length > 0) {
|
|
7285
|
+
fixes.push(`Switch active profile: codexuse profile switch ${profiles[0]?.name}`);
|
|
7286
|
+
}
|
|
7287
|
+
if (accountPool && (!accountPool.enabled || accountPool.activeApiKeyCount === 0)) {
|
|
7288
|
+
fixes.push("Pool quickstart: codexuse account-pool quickstart");
|
|
7289
|
+
}
|
|
7290
|
+
if (fixes.length > 0) {
|
|
7291
|
+
console.log("Fixes:");
|
|
7292
|
+
for (const fix of fixes) {
|
|
7293
|
+
console.log(`- ${fix}`);
|
|
7294
|
+
}
|
|
7295
|
+
return;
|
|
7296
|
+
}
|
|
7297
|
+
console.log("Ready.");
|
|
7298
|
+
}
|
|
7299
|
+
async function handleRunCommand(args) {
|
|
7300
|
+
const { flags, codexArgs } = splitCommandArgs(args);
|
|
7301
|
+
if (hasFlag(flags, "--help") || hasFlag(flags, "-h")) {
|
|
7302
|
+
console.log(`Usage:
|
|
7303
|
+
codexuse run --profile <name> -- <codex args>
|
|
7304
|
+
|
|
7305
|
+
Runs Codex under one saved CodexUse profile.`);
|
|
7306
|
+
return;
|
|
7307
|
+
}
|
|
7308
|
+
const profileName = readOption(flags, "--profile", "-p");
|
|
7309
|
+
if (!profileName) {
|
|
7310
|
+
throw new Error("Profile is required. Use --profile <name>.");
|
|
7311
|
+
}
|
|
7312
|
+
const manager = new ProfileManager();
|
|
7313
|
+
await runCodexWithProfile(manager, profileName, codexArgs);
|
|
7314
|
+
}
|
|
7315
|
+
async function handleBestCommand(args) {
|
|
7316
|
+
const { flags, codexArgs } = splitCommandArgs(args);
|
|
7317
|
+
if (hasFlag(flags, "--help") || hasFlag(flags, "-h")) {
|
|
7318
|
+
console.log(`Usage:
|
|
7319
|
+
codexuse best -- <codex args>
|
|
7320
|
+
|
|
7321
|
+
Picks the healthiest saved profile, then runs Codex. Auto-run requires Pro.`);
|
|
7322
|
+
return;
|
|
7323
|
+
}
|
|
7324
|
+
const codexPath = resolveCodexBinary();
|
|
7325
|
+
if (!codexPath) {
|
|
7326
|
+
throw new Error("Codex CLI not found. Install Codex CLI or set CODEX_BINARY.");
|
|
7327
|
+
}
|
|
7328
|
+
const manager = new ProfileManager();
|
|
7329
|
+
const profiles = await manager.listProfiles();
|
|
7330
|
+
const best = await selectBestProfile(manager, profiles, codexPath);
|
|
7331
|
+
if (!best) {
|
|
7332
|
+
throw new Error("No valid saved profiles found. Add one with `codexuse profile add <name>`.");
|
|
7333
|
+
}
|
|
7334
|
+
const dryRun = hasFlag(flags, "--dry-run");
|
|
7335
|
+
const license = await licenseService.getStatus();
|
|
7336
|
+
const summary = `${best.profile.name} (${formatUsagePercent(best.usedPercent)} used)`;
|
|
7337
|
+
if (!license.isPro) {
|
|
7338
|
+
console.log(`Best profile: ${summary}`);
|
|
7339
|
+
console.log("Auto-run is Pro. Free path:");
|
|
7340
|
+
console.log(` codexuse run --profile ${best.profile.name} -- ${codexArgs.join(" ")}`.trimEnd());
|
|
7341
|
+
return;
|
|
7342
|
+
}
|
|
7343
|
+
if (dryRun) {
|
|
7344
|
+
console.log(`Would run with profile: ${summary}`);
|
|
7345
|
+
return;
|
|
7346
|
+
}
|
|
7347
|
+
console.error(`CodexUse best -> ${summary}`);
|
|
7348
|
+
await runCodexWithProfile(manager, best.profile.name, codexArgs);
|
|
7349
|
+
}
|
|
7350
|
+
|
|
7351
|
+
// src/commands/daemon.ts
|
|
7352
|
+
var import_node_child_process6 = require("child_process");
|
|
6904
7353
|
var import_node_crypto5 = require("crypto");
|
|
6905
|
-
var
|
|
7354
|
+
var import_node_fs7 = __toESM(require("fs"));
|
|
6906
7355
|
var import_node_net = __toESM(require("net"));
|
|
6907
7356
|
var import_node_os4 = __toESM(require("os"));
|
|
6908
|
-
var
|
|
7357
|
+
var import_node_path10 = __toESM(require("path"));
|
|
6909
7358
|
|
|
6910
7359
|
// ../../packages/shared/src/core/internal-js-runtime.ts
|
|
6911
|
-
var
|
|
6912
|
-
var
|
|
7360
|
+
var import_node_child_process5 = require("child_process");
|
|
7361
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
6913
7362
|
var cachedBunBinary = null;
|
|
6914
7363
|
function hasBunRuntime() {
|
|
6915
7364
|
return typeof process.versions.bun === "string" && process.versions.bun.length > 0;
|
|
6916
7365
|
}
|
|
6917
7366
|
function buildRuntimePath(env) {
|
|
6918
7367
|
const homeDir = env.HOME ?? env.USERPROFILE ?? "";
|
|
6919
|
-
const pathHints = (env.CODEX_PATH_HINTS ?? "").split(
|
|
7368
|
+
const pathHints = (env.CODEX_PATH_HINTS ?? "").split(import_node_path9.default.delimiter).map((entry) => entry.trim()).filter(Boolean);
|
|
6920
7369
|
const entries = [
|
|
6921
7370
|
env.PATH ?? "",
|
|
6922
|
-
|
|
7371
|
+
import_node_path9.default.join(homeDir, ".bun", "bin"),
|
|
6923
7372
|
"/opt/homebrew/bin",
|
|
6924
7373
|
"/usr/local/bin",
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
7374
|
+
import_node_path9.default.join(homeDir, ".local", "bin"),
|
|
7375
|
+
import_node_path9.default.join(homeDir, ".fnm", "aliases", "default", "bin"),
|
|
7376
|
+
import_node_path9.default.join(homeDir, ".fnm", "current", "bin"),
|
|
6928
7377
|
...pathHints
|
|
6929
7378
|
];
|
|
6930
7379
|
return Array.from(
|
|
6931
7380
|
new Set(
|
|
6932
|
-
entries.flatMap((entry) => entry.split(
|
|
7381
|
+
entries.flatMap((entry) => entry.split(import_node_path9.default.delimiter)).map((entry) => entry.trim()).filter(Boolean)
|
|
6933
7382
|
)
|
|
6934
|
-
).join(
|
|
7383
|
+
).join(import_node_path9.default.delimiter);
|
|
6935
7384
|
}
|
|
6936
7385
|
function resolveConfiguredBunBinary(env) {
|
|
6937
7386
|
const candidates = [
|
|
@@ -6961,7 +7410,7 @@ function probeBunBinary(env) {
|
|
|
6961
7410
|
[
|
|
6962
7411
|
env.CODEXUSE_INTERNAL_BUN_BIN?.trim(),
|
|
6963
7412
|
env.BUN_BIN?.trim(),
|
|
6964
|
-
|
|
7413
|
+
import_node_path9.default.join(homeDir, ".bun", "bin", "bun"),
|
|
6965
7414
|
"/opt/homebrew/bin/bun",
|
|
6966
7415
|
"/usr/local/bin/bun",
|
|
6967
7416
|
"bun"
|
|
@@ -6969,7 +7418,7 @@ function probeBunBinary(env) {
|
|
|
6969
7418
|
)
|
|
6970
7419
|
);
|
|
6971
7420
|
for (const candidate of candidates) {
|
|
6972
|
-
const probe = (0,
|
|
7421
|
+
const probe = (0, import_node_child_process5.spawnSync)(candidate, ["--version"], {
|
|
6973
7422
|
env,
|
|
6974
7423
|
stdio: "ignore"
|
|
6975
7424
|
});
|
|
@@ -7022,18 +7471,18 @@ Notes:
|
|
|
7022
7471
|
}
|
|
7023
7472
|
function resolveServerEntry() {
|
|
7024
7473
|
const candidates = [
|
|
7025
|
-
|
|
7026
|
-
|
|
7474
|
+
import_node_path10.default.resolve(__dirname, "server", "index.mjs"),
|
|
7475
|
+
import_node_path10.default.resolve(__dirname, "../../../server/dist/index.mjs")
|
|
7027
7476
|
];
|
|
7028
7477
|
for (const candidate of candidates) {
|
|
7029
|
-
if (
|
|
7478
|
+
if (import_node_fs7.default.existsSync(candidate)) {
|
|
7030
7479
|
return candidate;
|
|
7031
7480
|
}
|
|
7032
7481
|
}
|
|
7033
7482
|
return candidates[0];
|
|
7034
7483
|
}
|
|
7035
7484
|
function resolveStateDir2() {
|
|
7036
|
-
return
|
|
7485
|
+
return import_node_path10.default.join(import_node_os4.default.homedir(), ".codexuse", "t3-daemon");
|
|
7037
7486
|
}
|
|
7038
7487
|
function reserveLoopbackPort(port = 0) {
|
|
7039
7488
|
return new Promise((resolve, reject) => {
|
|
@@ -7059,7 +7508,7 @@ function reserveLoopbackPort(port = 0) {
|
|
|
7059
7508
|
}
|
|
7060
7509
|
async function runDaemonStart(options) {
|
|
7061
7510
|
const entry = resolveServerEntry();
|
|
7062
|
-
if (!
|
|
7511
|
+
if (!import_node_fs7.default.existsSync(entry)) {
|
|
7063
7512
|
throw new Error(
|
|
7064
7513
|
`Missing bundled T3 server build output at ${entry}. Rebuild the CLI package with \`bun run build:cli\`.`
|
|
7065
7514
|
);
|
|
@@ -7070,7 +7519,7 @@ async function runDaemonStart(options) {
|
|
|
7070
7519
|
const port = await reserveLoopbackPort(options.port ?? 0);
|
|
7071
7520
|
const authToken = (0, import_node_crypto5.randomBytes)(24).toString("hex");
|
|
7072
7521
|
const stateDir = resolveStateDir2();
|
|
7073
|
-
const projectPath = options.projectPath ?
|
|
7522
|
+
const projectPath = options.projectPath ? import_node_path10.default.resolve(options.projectPath) : null;
|
|
7074
7523
|
const childCwd = projectPath ?? process.cwd();
|
|
7075
7524
|
const telegramBotToken = options.telegramBotToken?.trim() || null;
|
|
7076
7525
|
const runtime = resolveInternalBunRuntime({
|
|
@@ -7087,7 +7536,7 @@ async function runDaemonStart(options) {
|
|
|
7087
7536
|
CODEXUSE_TELEGRAM_BRIDGE_ENABLED: "1"
|
|
7088
7537
|
} : {}
|
|
7089
7538
|
});
|
|
7090
|
-
const child = (0,
|
|
7539
|
+
const child = (0, import_node_child_process6.spawn)(runtime.bin, [entry], {
|
|
7091
7540
|
cwd: childCwd,
|
|
7092
7541
|
env: runtime.env,
|
|
7093
7542
|
stdio: "inherit"
|
|
@@ -7245,114 +7694,6 @@ async function assertProfileCreationAllowed(profileManager) {
|
|
|
7245
7694
|
}
|
|
7246
7695
|
}
|
|
7247
7696
|
|
|
7248
|
-
// ../../packages/runtime-profiles/src/profiles/rate-limit-notifier.ts
|
|
7249
|
-
function maxUsedPercent(snapshot) {
|
|
7250
|
-
if (!snapshot) {
|
|
7251
|
-
return null;
|
|
7252
|
-
}
|
|
7253
|
-
const candidates = [
|
|
7254
|
-
snapshot.primary?.usedPercent,
|
|
7255
|
-
snapshot.secondary?.usedPercent
|
|
7256
|
-
].filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
7257
|
-
if (candidates.length === 0) {
|
|
7258
|
-
return null;
|
|
7259
|
-
}
|
|
7260
|
-
return Math.max(...candidates);
|
|
7261
|
-
}
|
|
7262
|
-
|
|
7263
|
-
// src/platform/codexCli.ts
|
|
7264
|
-
var import_node_child_process5 = require("child_process");
|
|
7265
|
-
var import_node_fs7 = require("fs");
|
|
7266
|
-
var import_node_path10 = __toESM(require("path"));
|
|
7267
|
-
var ENV_HINTS2 = ["CODEX_BINARY", "CODEX_CLI_PATH", "CODEX_PATH"];
|
|
7268
|
-
function fileExists2(candidate) {
|
|
7269
|
-
if (!candidate) return null;
|
|
7270
|
-
const resolved = import_node_path10.default.resolve(candidate);
|
|
7271
|
-
try {
|
|
7272
|
-
const stat2 = (0, import_node_fs7.statSync)(resolved);
|
|
7273
|
-
if (stat2.isFile()) return resolved;
|
|
7274
|
-
} catch {
|
|
7275
|
-
return null;
|
|
7276
|
-
}
|
|
7277
|
-
return null;
|
|
7278
|
-
}
|
|
7279
|
-
function resolveFromEnv() {
|
|
7280
|
-
for (const key of ENV_HINTS2) {
|
|
7281
|
-
const value = process.env[key];
|
|
7282
|
-
if (!value) continue;
|
|
7283
|
-
const resolved = fileExists2(value);
|
|
7284
|
-
if (resolved) return resolved;
|
|
7285
|
-
}
|
|
7286
|
-
return null;
|
|
7287
|
-
}
|
|
7288
|
-
function resolveFromPath() {
|
|
7289
|
-
const pathValue = process.env.PATH ?? "";
|
|
7290
|
-
const entries = pathValue.split(import_node_path10.default.delimiter).filter(Boolean);
|
|
7291
|
-
const names = process.platform === "win32" ? ["codex.exe", "codex.cmd", "codex.bat", "codex"] : ["codex"];
|
|
7292
|
-
for (const entry of entries) {
|
|
7293
|
-
for (const name of names) {
|
|
7294
|
-
const candidate = fileExists2(import_node_path10.default.join(entry, name));
|
|
7295
|
-
if (candidate) return candidate;
|
|
7296
|
-
}
|
|
7297
|
-
}
|
|
7298
|
-
return null;
|
|
7299
|
-
}
|
|
7300
|
-
function resolveCodexBinary() {
|
|
7301
|
-
return resolveFromEnv() || resolveFromPath();
|
|
7302
|
-
}
|
|
7303
|
-
function requireCodexBinary(context) {
|
|
7304
|
-
const resolved = resolveCodexBinary();
|
|
7305
|
-
if (resolved) return resolved;
|
|
7306
|
-
const hint = "Install Codex CLI (npm i -g @openai/codex) or set CODEX_BINARY.";
|
|
7307
|
-
const message = context ? `${context} ${hint}` : hint;
|
|
7308
|
-
throw new Error(message);
|
|
7309
|
-
}
|
|
7310
|
-
function buildCodexCommand2(codexPath, args) {
|
|
7311
|
-
const normalized = codexPath.toLowerCase();
|
|
7312
|
-
const isJs = normalized.endsWith(".js");
|
|
7313
|
-
if (isJs) {
|
|
7314
|
-
return { command: process.execPath, args: [codexPath, ...args], shell: false };
|
|
7315
|
-
}
|
|
7316
|
-
const useShell = process.platform === "win32";
|
|
7317
|
-
return { command: codexPath, args, shell: useShell };
|
|
7318
|
-
}
|
|
7319
|
-
function isHeadless() {
|
|
7320
|
-
if (process.env.CODEXUSE_HEADLESS === "1") return true;
|
|
7321
|
-
if (process.env.CI) return true;
|
|
7322
|
-
if (process.env.SSH_CONNECTION || process.env.SSH_TTY) return true;
|
|
7323
|
-
if (process.platform === "linux") {
|
|
7324
|
-
if (!process.env.DISPLAY && !process.env.WAYLAND_DISPLAY) return true;
|
|
7325
|
-
}
|
|
7326
|
-
return false;
|
|
7327
|
-
}
|
|
7328
|
-
function resolveLoginMode(preferred) {
|
|
7329
|
-
if (preferred === "browser" || preferred === "device") {
|
|
7330
|
-
return preferred;
|
|
7331
|
-
}
|
|
7332
|
-
const envMode = process.env.CODEXUSE_LOGIN_MODE;
|
|
7333
|
-
if (envMode === "browser" || envMode === "device") {
|
|
7334
|
-
return envMode;
|
|
7335
|
-
}
|
|
7336
|
-
return isHeadless() ? "device" : "browser";
|
|
7337
|
-
}
|
|
7338
|
-
async function runCodexLogin(mode) {
|
|
7339
|
-
const codexPath = requireCodexBinary("Codex CLI is required to login.");
|
|
7340
|
-
const resolvedMode = resolveLoginMode(mode ?? null);
|
|
7341
|
-
const loginArgs = resolvedMode === "device" ? ["login", "--device-auth"] : ["login"];
|
|
7342
|
-
const { command, args, shell } = buildCodexCommand2(codexPath, loginArgs);
|
|
7343
|
-
const child = (0, import_node_child_process5.spawn)(command, args, {
|
|
7344
|
-
stdio: "inherit",
|
|
7345
|
-
env: process.env,
|
|
7346
|
-
shell
|
|
7347
|
-
});
|
|
7348
|
-
const exitCode = await new Promise((resolve) => {
|
|
7349
|
-
child.on("close", (code) => resolve(code ?? 0));
|
|
7350
|
-
});
|
|
7351
|
-
if (exitCode !== 0) {
|
|
7352
|
-
throw new Error(`Codex CLI login failed (exit code ${exitCode}).`);
|
|
7353
|
-
}
|
|
7354
|
-
}
|
|
7355
|
-
|
|
7356
7697
|
// src/commands/profile.ts
|
|
7357
7698
|
function formatProfileLabel(name, displayName) {
|
|
7358
7699
|
if (displayName && displayName.trim() && displayName !== name) {
|
|
@@ -8161,7 +8502,7 @@ async function pushRemoteSnapshot(licenseKey, snapshot, options) {
|
|
|
8161
8502
|
var import_toml2 = __toESM(require_toml(), 1);
|
|
8162
8503
|
|
|
8163
8504
|
// ../../packages/runtime-codex/src/codex/config-metadata.ts
|
|
8164
|
-
var
|
|
8505
|
+
var import_node_child_process7 = require("child_process");
|
|
8165
8506
|
var import_promises = require("fs/promises");
|
|
8166
8507
|
var import_node_path11 = __toESM(require("path"), 1);
|
|
8167
8508
|
var CONFIG_SCHEMA_URL = "https://raw.githubusercontent.com/openai/codex/main/codex-rs/core/config.schema.json";
|
|
@@ -8271,9 +8612,9 @@ function isRecord5(value) {
|
|
|
8271
8612
|
function uniqueSorted(values) {
|
|
8272
8613
|
return Array.from(new Set(values)).sort((a, b) => a.localeCompare(b));
|
|
8273
8614
|
}
|
|
8274
|
-
async function
|
|
8615
|
+
async function runCommand2(command, args, timeoutMs = 3e3) {
|
|
8275
8616
|
return new Promise((resolve, reject) => {
|
|
8276
|
-
const child = (0,
|
|
8617
|
+
const child = (0, import_node_child_process7.spawn)(command, args, {
|
|
8277
8618
|
stdio: ["ignore", "pipe", "pipe"],
|
|
8278
8619
|
env: process.env
|
|
8279
8620
|
});
|
|
@@ -8308,7 +8649,7 @@ async function runCodexCommand(args) {
|
|
|
8308
8649
|
const isJsLauncher = codexPath.endsWith(".js");
|
|
8309
8650
|
const command = isJsLauncher ? process.execPath : codexPath;
|
|
8310
8651
|
const commandArgs = isJsLauncher ? [codexPath, ...args] : args;
|
|
8311
|
-
return
|
|
8652
|
+
return runCommand2(command, commandArgs);
|
|
8312
8653
|
}
|
|
8313
8654
|
function parseFeatureCatalog(output) {
|
|
8314
8655
|
const entries = [];
|
|
@@ -9797,7 +10138,8 @@ async function loadLegacySettingsPatch() {
|
|
|
9797
10138
|
autoRoll: autoRoll ? {
|
|
9798
10139
|
enabled: autoRoll.enabled,
|
|
9799
10140
|
warningThreshold: autoRoll.warningThreshold,
|
|
9800
|
-
switchThreshold: autoRoll.switchThreshold
|
|
10141
|
+
switchThreshold: autoRoll.switchThreshold,
|
|
10142
|
+
restartOfficialCodexOnAutoRoll: autoRoll.restartOfficialCodexOnAutoRoll
|
|
9801
10143
|
} : void 0
|
|
9802
10144
|
};
|
|
9803
10145
|
}
|
|
@@ -9993,7 +10335,8 @@ function mergeLegacyLocalStoragePatch(payload) {
|
|
|
9993
10335
|
patch.autoRoll = {
|
|
9994
10336
|
enabled: autoRoll.enabled,
|
|
9995
10337
|
warningThreshold: autoRoll.warningThreshold,
|
|
9996
|
-
switchThreshold: autoRoll.switchThreshold
|
|
10338
|
+
switchThreshold: autoRoll.switchThreshold,
|
|
10339
|
+
restartOfficialCodexOnAutoRoll: autoRoll.restartOfficialCodexOnAutoRoll
|
|
9997
10340
|
};
|
|
9998
10341
|
markSkippedIfPresent("codex:auto-roll-settings", true);
|
|
9999
10342
|
} else {
|
|
@@ -10267,7 +10610,7 @@ async function ensureCliStorageReady() {
|
|
|
10267
10610
|
}
|
|
10268
10611
|
|
|
10269
10612
|
// src/app/main.ts
|
|
10270
|
-
var VERSION = true ? "3.
|
|
10613
|
+
var VERSION = true ? "3.9.0" : "0.0.0";
|
|
10271
10614
|
async function runCli() {
|
|
10272
10615
|
const args = process.argv.slice(2);
|
|
10273
10616
|
if (args.length === 0) {
|
|
@@ -10285,6 +10628,18 @@ async function runCli() {
|
|
|
10285
10628
|
const command = args[0];
|
|
10286
10629
|
const rest = args.slice(1);
|
|
10287
10630
|
switch (command) {
|
|
10631
|
+
case "doctor":
|
|
10632
|
+
await ensureCliStorageReady();
|
|
10633
|
+
await handleDoctorCommand(rest);
|
|
10634
|
+
return;
|
|
10635
|
+
case "run":
|
|
10636
|
+
await ensureCliStorageReady();
|
|
10637
|
+
await handleRunCommand(rest);
|
|
10638
|
+
return;
|
|
10639
|
+
case "best":
|
|
10640
|
+
await ensureCliStorageReady();
|
|
10641
|
+
await handleBestCommand(rest);
|
|
10642
|
+
return;
|
|
10288
10643
|
case "account-pool":
|
|
10289
10644
|
case "accounts-pool":
|
|
10290
10645
|
await ensureCliStorageReady();
|